Esempio n. 1
0
  /**
   * Send the Java thread that represents this fiber to sleep until it recieves a resume or exit
   * message. On entry, assumes that the GIL is not held. On exit, holding the GIL.
   */
  public Object waitForResume() {
    RubyNode.notDesignedForCompilation();

    FiberMessage message = null;

    do {
      try {
        // TODO(cs) what is a suitable timeout?
        message = messageQueue.poll(1, TimeUnit.SECONDS);
      } catch (InterruptedException e) {
        // Poll again
      }
    } while (message == null);

    if (message instanceof FiberExitMessage) {
      throw new FiberExitException();
    }

    final FiberResumeMessage resumeMessage = (FiberResumeMessage) message;

    threadManager.enterGlobalLock(resumeMessage.getThread());

    fiberManager.setCurrentFiber(this);

    lastResumedByFiber = resumeMessage.getSendingFiber();
    return resumeMessage.getArg();
  }
Esempio n. 2
0
  /**
   * Send a message to a fiber by posting into a message queue. Doesn't explicitly notify the Java
   * thread (although the queue implementation may) and doesn't wait for the message to be received.
   * On entry, assumes the the GIL is held. On exit, not holding the GIL.
   */
  public void resume(RubyFiber sendingFiber, Object... args) {
    RubyNode.notDesignedForCompilation();

    Object arg;

    if (args.length == 0) {
      arg = getContext().getCoreLibrary().getNilObject();
    } else if (args.length == 1) {
      arg = args[0];
    } else {
      arg = RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(), args);
    }

    final RubyThread runningThread = threadManager.leaveGlobalLock();

    messageQueue.add(new FiberResumeMessage(runningThread, sendingFiber, arg));
  }