Skip to content

Commit 04dba41

Browse files
committed
Ensure leaveAndEnter() never returns null
1 parent da3bde0 commit 04dba41

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

src/main/java/org/truffleruby/core/fiber/FiberManager.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import com.oracle.truffle.api.TruffleSafepoint.Interrupter;
1616
import org.truffleruby.core.fiber.RubyFiber.FiberStatus;
1717

18-
import com.oracle.truffle.api.TruffleContext;
1918
import com.oracle.truffle.api.TruffleSafepoint;
2019
import org.truffleruby.RubyContext;
2120
import org.truffleruby.RubyLanguage;
@@ -75,9 +74,8 @@ private void createThreadToReceiveFirstMessage(RubyFiber fiber, Node currentNode
7574
fiber.initializeNode = null;
7675

7776
var sourceSection = block.getSharedMethodInfo().getSourceSection();
78-
final TruffleContext truffleContext = context.getEnv().getContext();
7977

80-
truffleContext.leaveAndEnter(currentNode, Interrupter.THREAD_INTERRUPT, (unused) -> {
78+
context.getThreadManager().leaveAndEnter(currentNode, Interrupter.THREAD_INTERRUPT, (unused) -> {
8179
Thread thread = context.getThreadManager().createFiberJavaThread(fiber, sourceSection,
8280
() -> beforeEnter(fiber, initializeNode),
8381
() -> fiberMain(context, fiber, block, initializeNode),
@@ -226,7 +224,7 @@ private void addToMessageQueue(RubyFiber fiber, FiberMessage message) {
226224
@TruffleBoundary
227225
private FiberMessage waitMessage(RubyFiber fiber, Node currentNode) throws InterruptedException {
228226
assertNotEntered("should have left context while waiting fiber message");
229-
return fiber.messageQueue.take();
227+
return Objects.requireNonNull(fiber.messageQueue.take());
230228
}
231229

232230
private void assertNotEntered(String reason) {
@@ -317,8 +315,7 @@ private FiberMessage resumeAndWait(RubyFiber fromFiber, RubyFiber toFiber, Fiber
317315
context.fiberManager.createThreadToReceiveFirstMessage(toFiber, currentNode);
318316
}
319317

320-
final TruffleContext truffleContext = context.getEnv().getContext();
321-
final FiberMessage message = truffleContext.leaveAndEnter(currentNode, Interrupter.THREAD_INTERRUPT,
318+
var message = context.getThreadManager().leaveAndEnter(currentNode, Interrupter.THREAD_INTERRUPT,
322319
(unused) -> {
323320
resume(fromFiber, toFiber, operation, descriptor, args);
324321
return waitMessage(fromFiber, currentNode);
@@ -329,8 +326,7 @@ private FiberMessage resumeAndWait(RubyFiber fromFiber, RubyFiber toFiber, Fiber
329326

330327
@TruffleBoundary
331328
public void safepoint(RubyFiber fromFiber, RubyFiber fiber, SafepointAction action, Node currentNode) {
332-
final TruffleContext truffleContext = context.getEnv().getContext();
333-
final FiberResumeMessage returnMessage = (FiberResumeMessage) truffleContext.leaveAndEnter(currentNode,
329+
var returnMessage = (FiberResumeMessage) context.getThreadManager().leaveAndEnter(currentNode,
334330
Interrupter.THREAD_INTERRUPT, (unused) -> {
335331
addToMessageQueue(fiber, new FiberSafepointMessage(fromFiber, action));
336332
return waitMessage(fromFiber, currentNode);
@@ -385,8 +381,7 @@ public void killOtherFibers(RubyThread thread) {
385381
final TruffleSafepoint safepoint = TruffleSafepoint.getCurrent();
386382
boolean allowSideEffects = safepoint.setAllowSideEffects(false);
387383
try {
388-
final TruffleContext truffleContext = context.getEnv().getContext();
389-
truffleContext.leaveAndEnter(DummyNode.INSTANCE, Interrupter.THREAD_INTERRUPT, (unused) -> {
384+
context.getThreadManager().leaveAndEnter(DummyNode.INSTANCE, Interrupter.THREAD_INTERRUPT, (unused) -> {
390385
doKillOtherFibers(thread);
391386
return BlockingAction.SUCCESS;
392387
}, null);

src/main/java/org/truffleruby/core/thread/ThreadManager.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import java.lang.reflect.InvocationTargetException;
1313
import java.lang.reflect.Method;
14+
import java.util.Objects;
1415
import java.util.Set;
1516
import java.util.Timer;
1617
import java.util.concurrent.ConcurrentHashMap;
@@ -23,6 +24,7 @@
2324
import com.oracle.truffle.api.CompilerAsserts;
2425
import com.oracle.truffle.api.CompilerDirectives;
2526
import com.oracle.truffle.api.CompilerDirectives.ValueType;
27+
import com.oracle.truffle.api.TruffleContext;
2628
import com.oracle.truffle.api.TruffleOptions;
2729
import com.oracle.truffle.api.TruffleSafepoint;
2830
import com.oracle.truffle.api.TruffleSafepoint.Interrupter;
@@ -607,6 +609,15 @@ public <T> T runUntilResult(Node currentNode, BlockingAction<T> action, Runnable
607609
}
608610
}
609611

612+
/** Same as {@link TruffleContext#leaveAndEnter} but ensures it never returns null. Also the interruptible must
613+
* never return null. */
614+
public <T, R> R leaveAndEnter(Node node, Interrupter interrupter, InterruptibleFunction<T, R> interruptible,
615+
T object) {
616+
final TruffleContext truffleContext = context.getEnv().getContext();
617+
R result = truffleContext.leaveAndEnter(node, interrupter, interruptible, object);
618+
return Objects.requireNonNull(result);
619+
}
620+
610621
@TruffleBoundary
611622
Interrupter getNativeCallInterrupter() {
612623
if (nativeInterrupt) {

0 commit comments

Comments
 (0)