|
59 | 59 | import org.truffleruby.core.InterruptMode;
|
60 | 60 | import org.truffleruby.core.VMPrimitiveNodes.VMRaiseExceptionNode;
|
61 | 61 | import org.truffleruby.core.array.ArrayGuards;
|
| 62 | +import org.truffleruby.core.array.ArrayToObjectArrayNode; |
62 | 63 | import org.truffleruby.core.array.RubyArray;
|
63 | 64 | import org.truffleruby.core.array.library.ArrayStoreLibrary;
|
64 | 65 | import org.truffleruby.core.basicobject.RubyBasicObject;
|
|
104 | 105 | import com.oracle.truffle.api.nodes.Node;
|
105 | 106 | import com.oracle.truffle.api.object.Shape;
|
106 | 107 | import com.oracle.truffle.api.profiles.BranchProfile;
|
107 |
| -import com.oracle.truffle.api.profiles.LoopConditionProfile; |
108 | 108 | import com.oracle.truffle.api.source.SourceSection;
|
109 | 109 |
|
110 | 110 | @CoreModule(value = "Thread", isClass = true)
|
@@ -833,36 +833,30 @@ protected RubyBasicObject getFiberLocals(RubyThread thread) {
|
833 | 833 |
|
834 | 834 | /** Similar to {@link ThreadManager#runUntilResult(Node, ThreadManager.BlockingAction)} but purposed for blocking
|
835 | 835 | * native calls. If the {@link SafepointManager} needs to interrupt the thread, it will send a SIGVTALRM to abort
|
836 |
| - * the blocking syscall and the action will return NotProvided if the syscall fails with errno=EINTR, meaning it was |
837 |
| - * interrupted. */ |
| 836 | + * the blocking syscall and the syscall will return -1 with errno=EINTR, meaning it was interrupted. */ |
838 | 837 | @Primitive(name = "thread_run_blocking_nfi_system_call")
|
839 | 838 | public static abstract class ThreadRunBlockingSystemCallNode extends PrimitiveArrayArgumentsNode {
|
840 | 839 |
|
841 | 840 | @Specialization
|
842 |
| - protected Object runBlockingSystemCall(RubyProc block, |
843 |
| - @Cached("createCountingProfile()") LoopConditionProfile loopProfile, |
844 |
| - @Cached YieldNode yieldNode) { |
| 841 | + protected Object runBlockingSystemCall(Object executable, RubyArray argsArray, |
| 842 | + @Cached GetCurrentRubyThreadNode getCurrentRubyThreadNode, |
| 843 | + @CachedLibrary(limit = "1") InteropLibrary receivers, |
| 844 | + @Cached ArrayToObjectArrayNode arrayToObjectArrayNode, |
| 845 | + @Cached TranslateInteropExceptionNode translateInteropExceptionNode) { |
| 846 | + final Object[] args = arrayToObjectArrayNode.executeToObjectArray(argsArray); |
| 847 | + final RubyThread thread = getCurrentRubyThreadNode.execute(); |
| 848 | + |
845 | 849 | final ThreadManager threadManager = getContext().getThreadManager();
|
846 | 850 | final UnblockingAction unblockingAction = threadManager.getNativeCallUnblockingAction();
|
847 |
| - final RubyThread thread = threadManager.getCurrentThread(); |
848 | 851 | final UnblockingActionHolder actionHolder = threadManager.getActionHolder(Thread.currentThread());
|
849 | 852 |
|
850 | 853 | final UnblockingAction oldAction = actionHolder.changeTo(unblockingAction);
|
| 854 | + final ThreadStatus status = thread.status; |
| 855 | + thread.status = ThreadStatus.SLEEP; |
851 | 856 | try {
|
852 |
| - Object result; |
853 |
| - do { |
854 |
| - final ThreadStatus status = thread.status; |
855 |
| - thread.status = ThreadStatus.SLEEP; |
856 |
| - |
857 |
| - try { |
858 |
| - result = yieldNode.executeDispatch(block); |
859 |
| - } finally { |
860 |
| - thread.status = status; |
861 |
| - } |
862 |
| - } while (loopProfile.profile(result == NotProvided.INSTANCE)); |
863 |
| - |
864 |
| - return result; |
| 857 | + return InteropNodes.execute(executable, args, receivers, translateInteropExceptionNode); |
865 | 858 | } finally {
|
| 859 | + thread.status = status; |
866 | 860 | actionHolder.restore(oldAction);
|
867 | 861 | }
|
868 | 862 | }
|
|
0 commit comments