|
60 | 60 | import org.truffleruby.core.InterruptMode;
|
61 | 61 | import org.truffleruby.core.VMPrimitiveNodes.VMRaiseExceptionNode;
|
62 | 62 | import org.truffleruby.core.array.ArrayGuards;
|
| 63 | +import org.truffleruby.core.array.ArrayToObjectArrayNode; |
63 | 64 | import org.truffleruby.core.array.RubyArray;
|
64 | 65 | import org.truffleruby.core.array.library.ArrayStoreLibrary;
|
65 | 66 | import org.truffleruby.core.basicobject.RubyBasicObject;
|
|
105 | 106 | import com.oracle.truffle.api.nodes.Node;
|
106 | 107 | import com.oracle.truffle.api.object.Shape;
|
107 | 108 | import com.oracle.truffle.api.profiles.BranchProfile;
|
108 |
| -import com.oracle.truffle.api.profiles.LoopConditionProfile; |
109 | 109 | import com.oracle.truffle.api.source.SourceSection;
|
110 | 110 |
|
111 | 111 | @CoreModule(value = "Thread", isClass = true)
|
@@ -872,36 +872,30 @@ protected RubyBasicObject getFiberLocals(RubyThread thread) {
|
872 | 872 |
|
873 | 873 | /** Similar to {@link ThreadManager#runUntilResult(Node, ThreadManager.BlockingAction)} but purposed for blocking
|
874 | 874 | * native calls. If the {@link SafepointManager} needs to interrupt the thread, it will send a SIGVTALRM to abort
|
875 |
| - * the blocking syscall and the action will return NotProvided if the syscall fails with errno=EINTR, meaning it was |
876 |
| - * interrupted. */ |
| 875 | + * the blocking syscall and the syscall will return -1 with errno=EINTR, meaning it was interrupted. */ |
877 | 876 | @Primitive(name = "thread_run_blocking_nfi_system_call")
|
878 | 877 | public static abstract class ThreadRunBlockingSystemCallNode extends PrimitiveArrayArgumentsNode {
|
879 | 878 |
|
880 | 879 | @Specialization
|
881 |
| - protected Object runBlockingSystemCall(RubyProc block, |
882 |
| - @Cached("createCountingProfile()") LoopConditionProfile loopProfile, |
883 |
| - @Cached YieldNode yieldNode) { |
| 880 | + protected Object runBlockingSystemCall(Object executable, RubyArray argsArray, |
| 881 | + @Cached GetCurrentRubyThreadNode getCurrentRubyThreadNode, |
| 882 | + @CachedLibrary(limit = "1") InteropLibrary receivers, |
| 883 | + @Cached ArrayToObjectArrayNode arrayToObjectArrayNode, |
| 884 | + @Cached TranslateInteropExceptionNode translateInteropExceptionNode) { |
| 885 | + final Object[] args = arrayToObjectArrayNode.executeToObjectArray(argsArray); |
| 886 | + final RubyThread thread = getCurrentRubyThreadNode.execute(); |
| 887 | + |
884 | 888 | final ThreadManager threadManager = getContext().getThreadManager();
|
885 | 889 | final UnblockingAction unblockingAction = threadManager.getNativeCallUnblockingAction();
|
886 |
| - final RubyThread thread = threadManager.getCurrentThread(); |
887 | 890 | final UnblockingActionHolder actionHolder = threadManager.getActionHolder(Thread.currentThread());
|
888 | 891 |
|
889 | 892 | final UnblockingAction oldAction = actionHolder.changeTo(unblockingAction);
|
| 893 | + final ThreadStatus status = thread.status; |
| 894 | + thread.status = ThreadStatus.SLEEP; |
890 | 895 | try {
|
891 |
| - Object result; |
892 |
| - do { |
893 |
| - final ThreadStatus status = thread.status; |
894 |
| - thread.status = ThreadStatus.SLEEP; |
895 |
| - |
896 |
| - try { |
897 |
| - result = yieldNode.executeDispatch(block); |
898 |
| - } finally { |
899 |
| - thread.status = status; |
900 |
| - } |
901 |
| - } while (loopProfile.profile(result == NotProvided.INSTANCE)); |
902 |
| - |
903 |
| - return result; |
| 896 | + return InteropNodes.execute(executable, args, receivers, translateInteropExceptionNode); |
904 | 897 | } finally {
|
| 898 | + thread.status = status; |
905 | 899 | actionHolder.restore(oldAction);
|
906 | 900 | }
|
907 | 901 | }
|
|
0 commit comments