|
76 | 76 | import org.truffleruby.core.symbol.RubySymbol;
|
77 | 77 | import org.truffleruby.core.thread.ThreadManager.UnblockingAction;
|
78 | 78 | import org.truffleruby.core.thread.ThreadManager.UnblockingActionHolder;
|
| 79 | +import org.truffleruby.interop.InteropNodes; |
| 80 | +import org.truffleruby.interop.TranslateInteropExceptionNode; |
79 | 81 | import org.truffleruby.language.Nil;
|
80 | 82 | import org.truffleruby.language.NotProvided;
|
81 | 83 | import org.truffleruby.language.SafepointAction;
|
|
88 | 90 | import org.truffleruby.language.objects.shared.SharedObjects;
|
89 | 91 | import org.truffleruby.language.yield.YieldNode;
|
90 | 92 |
|
| 93 | +import com.oracle.truffle.api.CompilerDirectives; |
91 | 94 | import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
|
92 | 95 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
93 | 96 | import com.oracle.truffle.api.dsl.Cached;
|
94 | 97 | import com.oracle.truffle.api.dsl.ImportStatic;
|
95 | 98 | import com.oracle.truffle.api.dsl.Specialization;
|
| 99 | +import com.oracle.truffle.api.interop.InteropException; |
| 100 | +import com.oracle.truffle.api.interop.InteropLibrary; |
96 | 101 | import com.oracle.truffle.api.library.CachedLibrary;
|
97 | 102 | import com.oracle.truffle.api.nodes.Node;
|
98 | 103 | import com.oracle.truffle.api.object.Shape;
|
@@ -503,46 +508,49 @@ protected RubyThread wakeup(RubyThread rubyThread) {
|
503 | 508 | }
|
504 | 509 |
|
505 | 510 | @NonStandard
|
506 |
| - @CoreMethod(names = "unblock", required = 2) |
507 |
| - public abstract static class UnblockNode extends YieldingCoreMethodNode { |
| 511 | + @Primitive(name = "call_with_unblocking_function") |
| 512 | + public abstract static class CallWithUnblockingFunctionNode extends PrimitiveArrayArgumentsNode { |
508 | 513 |
|
509 |
| - @Specialization |
510 |
| - protected Object unblock(RubyThread thread, Object unblocker, RubyProc runner, |
511 |
| - @Cached("createCountingProfile()") LoopConditionProfile loopProfile) { |
| 514 | + @Specialization(limit = "getCacheLimit()") |
| 515 | + protected Object call(RubyThread thread, Object function, Object arg, Object unblocker, Object unblockerArg, |
| 516 | + @CachedLibrary("function") InteropLibrary receivers, |
| 517 | + @Cached TranslateInteropExceptionNode translateInteropExceptionNode) { |
512 | 518 | final ThreadManager threadManager = getContext().getThreadManager();
|
513 | 519 | final UnblockingAction unblockingAction;
|
514 | 520 | if (unblocker == nil) {
|
515 | 521 | unblockingAction = threadManager.getNativeCallUnblockingAction();
|
516 | 522 | } else {
|
517 |
| - unblockingAction = makeUnblockingAction((RubyProc) unblocker); |
| 523 | + unblockingAction = makeUnblockingAction(unblocker, unblockerArg); |
518 | 524 | }
|
519 |
| - final UnblockingActionHolder actionHolder = threadManager.getActionHolder(Thread.currentThread()); |
520 | 525 |
|
| 526 | + final UnblockingActionHolder actionHolder = threadManager.getActionHolder(Thread.currentThread()); |
521 | 527 | final UnblockingAction oldAction = actionHolder.changeTo(unblockingAction);
|
| 528 | + final ThreadStatus status = thread.status; |
| 529 | + thread.status = ThreadStatus.SLEEP; |
522 | 530 | try {
|
523 |
| - Object result; |
524 |
| - do { |
525 |
| - final ThreadStatus status = thread.status; |
526 |
| - thread.status = ThreadStatus.SLEEP; |
527 |
| - |
528 |
| - try { |
529 |
| - result = yield(runner); |
530 |
| - } finally { |
531 |
| - thread.status = status; |
532 |
| - } |
533 |
| - } while (loopProfile.profile(result == null)); |
534 |
| - |
535 |
| - return result; |
| 531 | + return InteropNodes.execute(function, new Object[]{ arg }, receivers, translateInteropExceptionNode); |
536 | 532 | } finally {
|
| 533 | + thread.status = status; |
537 | 534 | actionHolder.restore(oldAction);
|
| 535 | + |
538 | 536 | }
|
539 | 537 | }
|
540 | 538 |
|
541 | 539 | @TruffleBoundary
|
542 |
| - private UnblockingAction makeUnblockingAction(RubyProc unblocker) { |
543 |
| - return () -> yield(unblocker); |
| 540 | + private UnblockingAction makeUnblockingAction(Object function, Object argument) { |
| 541 | + assert InteropLibrary.getUncached().isExecutable(function); |
| 542 | + return () -> { |
| 543 | + try { |
| 544 | + InteropLibrary.getUncached().execute(function, argument); |
| 545 | + } catch (InteropException e) { |
| 546 | + throw CompilerDirectives.shouldNotReachHere(e); |
| 547 | + } |
| 548 | + }; |
544 | 549 | }
|
545 | 550 |
|
| 551 | + protected int getCacheLimit() { |
| 552 | + return getContext().getOptions().DISPATCH_CACHE; |
| 553 | + } |
546 | 554 | }
|
547 | 555 |
|
548 | 556 | @CoreMethod(names = "list", onSingleton = true)
|
|
0 commit comments