Skip to content

Commit b39fc43

Browse files
committed
Use lock for interop calls if multi-threaded.
1 parent 7b7dfc4 commit b39fc43

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,8 @@ protected boolean isThreadAccessAllowed(Thread thread, boolean singleThreaded) {
618618

619619
@Override
620620
protected void initializeMultiThreading(PythonContext context) {
621-
PythonContext.getSingleThreadedAssumption().invalidate();
621+
context.createInteropLock();
622+
context.getSingleThreadedAssumption().invalidate();
622623
}
623624

624625
@Override

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ public abstract static class IndirectCallContext {
288288
* </p>
289289
*/
290290
public static PException enter(VirtualFrame frame, PythonContext context, Node callNode) {
291+
if (!context.getSingleThreadedAssumption().isValid()) {
292+
context.acquireInteropLock();
293+
}
291294
PFrame.Reference prev = context.popTopFrameInfo();
292295
assert prev == null : "trying to call from Python to a foreign function, but we didn't clear the topframeref. " +
293296
"This indicates that a call into Python code happened without a proper enter through ForeignToPythonCallContext";
@@ -303,6 +306,9 @@ public static void exit(PythonContext context, PException savedExceptionState) {
303306
if (context != null) {
304307
context.popTopFrameInfo();
305308
ExceptionContext.exit(context, savedExceptionState);
309+
if (!context.getSingleThreadedAssumption().isValid()) {
310+
context.releaseInteropLock();
311+
}
306312
}
307313
}
308314
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.io.OutputStream;
3535
import java.util.HashMap;
3636
import java.util.concurrent.atomic.AtomicLong;
37+
import java.util.concurrent.locks.Lock;
3738
import java.util.concurrent.locks.ReentrantLock;
3839
import java.util.function.Supplier;
3940

@@ -102,8 +103,12 @@ public final class PythonContext {
102103
private OutputStream err;
103104
private InputStream in;
104105
@CompilationFinal private Object capiLibrary = null;
106+
private final Assumption singleThreaded = Truffle.getRuntime().createAssumption("single Threaded");
107+
105108
private static final Assumption singleNativeContext = Truffle.getRuntime().createAssumption("single native context assumption");
106-
private static final Assumption singleThreaded = Truffle.getRuntime().createAssumption("single Threaded");
109+
110+
/* A lock for interop calls when this context is used by multiple threads. */
111+
private Lock interopLock;
107112

108113
@CompilationFinal private HashingStorage.Equivalence slowPathEquivalence;
109114

@@ -402,7 +407,7 @@ public static Assumption getSingleNativeContextAssumption() {
402407
return singleNativeContext;
403408
}
404409

405-
public static Assumption getSingleThreadedAssumption() {
410+
public Assumption getSingleThreadedAssumption() {
406411
return singleThreaded;
407412
}
408413

@@ -452,4 +457,19 @@ public Object getSingletonNativePtr(PythonAbstractObject obj) {
452457
}
453458
return null;
454459
}
460+
461+
@TruffleBoundary
462+
public void acquireInteropLock() {
463+
interopLock.lock();
464+
}
465+
466+
@TruffleBoundary
467+
public void releaseInteropLock() {
468+
interopLock.unlock();
469+
}
470+
471+
@TruffleBoundary
472+
public void createInteropLock() {
473+
interopLock = new ReentrantLock();
474+
}
455475
}

0 commit comments

Comments
 (0)