Beispiel #1
0
  public boolean waitForIO(ThreadContext context, RubyIO io, int ops) {
    Channel channel = io.getChannel();

    if (!(channel instanceof SelectableChannel)) {
      return true;
    }
    try {
      io.addBlockingThread(this);
      blockingIO = BlockingIO.newCondition(channel, ops);
      boolean ready = blockingIO.await();

      // check for thread events, in case we've been woken up to die
      pollThreadEvents();
      return ready;
    } catch (IOException ioe) {
      throw context.runtime.newRuntimeError("Error with selector: " + ioe);
    } catch (InterruptedException ex) {
      // FIXME: not correct exception
      throw context.runtime.newRuntimeError("Interrupted");
    } finally {
      blockingIO = null;
      io.removeBlockingThread(this);
    }
  }
Beispiel #2
0
  public boolean select(Channel channel, RubyIO io, int ops, long timeout) {
    if (channel instanceof SelectableChannel) {
      SelectableChannel selectable = (SelectableChannel) channel;

      synchronized (selectable.blockingLock()) {
        boolean oldBlocking = selectable.isBlocking();

        SelectionKey key = null;
        try {
          selectable.configureBlocking(false);

          if (io != null) io.addBlockingThread(this);
          currentSelector = getRuntime().getSelectorPool().get(selectable.provider());

          key = selectable.register(currentSelector, ops);

          beforeBlockingCall();
          int result;
          if (timeout < 0) {
            result = currentSelector.select();
          } else if (timeout == 0) {
            result = currentSelector.selectNow();
          } else {
            result = currentSelector.select(timeout);
          }

          // check for thread events, in case we've been woken up to die
          pollThreadEvents();

          if (result == 1) {
            Set<SelectionKey> keySet = currentSelector.selectedKeys();

            if (keySet.iterator().next() == key) {
              return true;
            }
          }

          return false;
        } catch (IOException ioe) {
          throw getRuntime().newIOErrorFromException(ioe);
        } finally {
          // Note: I don't like ignoring these exceptions, but it's
          // unclear how likely they are to happen or what damage we
          // might do by ignoring them. Note that the pieces are separate
          // so that we can ensure one failing does not affect the others
          // running.

          // clean up the key in the selector
          try {
            if (key != null) key.cancel();
            if (currentSelector != null) currentSelector.selectNow();
          } catch (Exception e) {
            // ignore
          }

          // shut down and null out the selector
          try {
            if (currentSelector != null) {
              getRuntime().getSelectorPool().put(currentSelector);
            }
          } catch (Exception e) {
            // ignore
          } finally {
            currentSelector = null;
          }

          // remove this thread as a blocker against the given IO
          if (io != null) io.removeBlockingThread(this);

          // go back to previous blocking state on the selectable
          try {
            selectable.configureBlocking(oldBlocking);
          } catch (Exception e) {
            // ignore
          }

          // clear thread state from blocking call
          afterBlockingCall();
        }
      }
    } else {
      // can't select, just have to do a blocking call
      return true;
    }
  }