public ByteList doReceiveNonblock(ThreadContext context, int length) {
    Ruby runtime = context.runtime;
    Channel channel = getChannel();

    if (!(channel instanceof SelectableChannel)) {
      if (runtime.is1_9()) {
        throw runtime.newErrnoEAGAINReadableError(
            channel.getClass().getName() + " does not support nonblocking");
      } else {
        throw runtime.newErrnoEAGAINError(
            channel.getClass().getName() + " does not support nonblocking");
      }
    }

    SelectableChannel selectable = (SelectableChannel) channel;

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

      try {
        selectable.configureBlocking(false);

        try {
          return doReceive(context, length);
        } finally {
          selectable.configureBlocking(oldBlocking);
        }

      } catch (IOException e) {
        throw runtime.newIOErrorFromException(e);
      }
    }
  }
  @JRubyMethod
  public IRubyObject recv_nonblock(ThreadContext context, IRubyObject _length) {
    Ruby runtime = context.runtime;

    ByteList bytes = doReceiveNonblock(context, RubyNumeric.fix2int(_length));

    if (bytes == null) {
      if (runtime.is1_9()) {
        throw runtime.newErrnoEAGAINReadableError("recvfrom(2)");
      } else {
        throw runtime.newErrnoEAGAINError("recvfrom(2)");
      }
    }

    return RubyString.newString(runtime, bytes);
  }
Exemple #3
0
  @JRubyMethod(name = "accept_nonblock")
  public IRubyObject accept_nonblock(ThreadContext context) {
    Ruby runtime = context.runtime;
    RubyTCPSocket socket = new RubyTCPSocket(runtime, runtime.getClass("TCPSocket"));
    Selector selector = null;

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

      try {
        ssc.configureBlocking(false);
        selector = SelectorFactory.openWithRetryFrom(runtime, SelectorProvider.provider());

        boolean ready = context.getThread().select(this, SelectionKey.OP_ACCEPT, 0);

        if (!ready) {
          // no connection immediately accepted, let them try again
          throw runtime.newErrnoEAGAINError("Resource temporarily unavailable");

        } else {
          // otherwise one key has been selected (ours) so we get the channel and hand it off
          socket.initSocket(
              context.runtime,
              new ChannelDescriptor(ssc.accept(), newModeFlags(runtime, ModeFlags.RDWR)));

          return socket;
        }

      } catch (IOException e) {
        throw SocketUtils.sockerr(context.runtime, "problem when accepting");

      } finally {
        try {
          if (selector != null) selector.close();
        } catch (Exception e) {
        }
        try {
          ssc.configureBlocking(oldBlocking);
        } catch (IOException ioe) {
        }
      }
    }
  }