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); }
@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) { } } } }