@TruffleBoundary private SafepointAction step(Node currentNode, boolean isDrivingThread) { final DynamicObject thread = context.getThreadManager().getCurrentThread(); // wait other threads to reach their safepoint phaser.arriveAndAwaitAdvance(); if (isDrivingThread) { assumption = Truffle.getRuntime().createAssumption("SafepointManager"); } // wait the assumption to be renewed phaser.arriveAndAwaitAdvance(); // Read these while in the safepoint. SafepointAction deferredAction = deferred ? action : null; try { if (!deferred && thread != null && Layouts.THREAD.getStatus(thread) != Status.ABORTING) { action.run(thread, currentNode); } } finally { // wait other threads to finish their action phaser.arriveAndAwaitAdvance(); } return deferredAction; }
@TruffleBoundary private void assumptionInvalidated(Node currentNode, boolean fromBlockingCall) { final DynamicObject thread = context.getThreadManager().getCurrentThread(); final InterruptMode interruptMode = Layouts.THREAD.getInterruptMode(thread); final boolean interruptible = (interruptMode == InterruptMode.IMMEDIATE) || (fromBlockingCall && interruptMode == InterruptMode.ON_BLOCKING); if (!interruptible) { Thread.currentThread().interrupt(); // keep the interrupt flag return; // interrupt me later } SafepointAction deferredAction = step(currentNode, false); // We're now running again normally and can run deferred actions if (deferredAction != null) { deferredAction.run(thread, currentNode); } }