Skip to content

Commit 60ba3d9

Browse files
committed
Pin virtual threads when acquiring monitors via JNI.
1 parent 8cb2a29 commit 60ba3d9

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

substratevm/src/com.oracle.svm.jni/src/com/oracle/svm/jni/functions/JNIFunctions.java

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
import com.oracle.svm.core.snippets.KnownIntrinsics;
7777
import com.oracle.svm.core.stack.StackOverflowCheck;
7878
import com.oracle.svm.core.thread.VMThreads.SafepointBehavior;
79+
import com.oracle.svm.core.thread.VirtualThreads;
7980
import com.oracle.svm.core.util.Utf8;
8081
import com.oracle.svm.core.util.VMError;
8182
import com.oracle.svm.jni.JNIObjectHandles;
@@ -1015,10 +1016,38 @@ static int MonitorEnter(JNIEnvironment env, JNIObjectHandle handle) {
10151016
if (obj == null) {
10161017
throw new NullPointerException();
10171018
}
1018-
MonitorSupport.singleton().monitorEnter(obj);
1019-
assert Thread.holdsLock(obj);
1020-
JNIThreadOwnedMonitors.entered(obj);
1021-
return JNIErrors.JNI_OK();
1019+
boolean pinned = false;
1020+
if (VirtualThreads.isSupported() && VirtualThreads.get().isVirtual(Thread.currentThread())) {
1021+
// Acquiring monitors via JNI associates them with the carrier thread via
1022+
// JNIThreadOwnedMonitors, so we must pin the virtual thread
1023+
try {
1024+
VirtualThreads.get().pinCurrent();
1025+
} catch (IllegalStateException e) { // too many pins
1026+
throw new IllegalMonitorStateException();
1027+
}
1028+
pinned = true;
1029+
}
1030+
boolean acquired = false;
1031+
try {
1032+
MonitorSupport.singleton().monitorEnter(obj);
1033+
assert Thread.holdsLock(obj);
1034+
acquired = true;
1035+
1036+
JNIThreadOwnedMonitors.entered(obj);
1037+
return JNIErrors.JNI_OK();
1038+
} catch (Throwable t) {
1039+
try {
1040+
if (acquired) {
1041+
MonitorSupport.singleton().monitorExit(obj);
1042+
}
1043+
if (pinned) {
1044+
VirtualThreads.get().unpinCurrent();
1045+
}
1046+
} catch (Throwable u) {
1047+
throw VMError.shouldNotReachHere(u);
1048+
}
1049+
throw t;
1050+
}
10221051
}
10231052

10241053
/*
@@ -1036,6 +1065,13 @@ static int MonitorExit(JNIEnvironment env, JNIObjectHandle handle) {
10361065
}
10371066
MonitorSupport.singleton().monitorExit(obj);
10381067
JNIThreadOwnedMonitors.exited(obj);
1068+
if (VirtualThreads.isSupported() && VirtualThreads.get().isVirtual(Thread.currentThread())) {
1069+
try {
1070+
VirtualThreads.get().unpinCurrent();
1071+
} catch (IllegalStateException e) { // not pinned?
1072+
throw new IllegalMonitorStateException();
1073+
}
1074+
}
10391075
return JNIErrors.JNI_OK();
10401076
}
10411077

0 commit comments

Comments
 (0)