Пример #1
0
  public static IRubyObject doAccept(RubySocket sock, ThreadContext context, boolean ex) {
    Ruby runtime = context.runtime;

    Channel channel = sock.getChannel();

    try {
      if (channel instanceof ServerSocketChannel) {
        ServerSocketChannel serverChannel = (ServerSocketChannel) sock.getChannel();

        SocketChannel socket = serverChannel.accept();

        if (socket == null) {
          // This appears to be undocumented in JDK; null as a sentinel value
          // for a nonblocking accept with nothing available. We raise for Ruby.
          // indicates that no connection is available in non-blocking mode
          if (!ex) return runtime.newSymbol("wait_readable");
          throw runtime.newErrnoEAGAINReadableError("accept(2) would block");
        }

        RubySocket rubySocket = new RubySocket(runtime, runtime.getClass("Socket"));
        rubySocket.initFromServer(runtime, sock, socket);

        return runtime.newArray(
            rubySocket,
            new Addrinfo(runtime, runtime.getClass("Addrinfo"), socket.getRemoteAddress()));
      }
      throw runtime.newErrnoENOPROTOOPTError();
    } catch (IllegalBlockingModeException e) {
      // indicates that no connection is available in non-blocking mode
      if (!ex) return runtime.newSymbol("wait_readable");
      throw runtime.newErrnoEAGAINReadableError("accept(2) would block");
    } catch (IOException e) {
      throw sockerr(runtime, e.getLocalizedMessage(), e);
    }
  }
Пример #2
0
  public static IRubyObject doAcceptNonblock(RubySocket sock, ThreadContext context, boolean ex) {
    try {
      Channel channel = sock.getChannel();
      if (channel instanceof SelectableChannel) {
        SelectableChannel selectable = (SelectableChannel) channel;

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

          try {
            selectable.configureBlocking(false);

            IRubyObject socket = doAccept(sock, context, ex);
            if (!(socket instanceof RubySocket)) return socket;
            SocketChannel socketChannel = (SocketChannel) ((RubySocket) socket).getChannel();
            InetSocketAddress addr =
                (InetSocketAddress) socketChannel.socket().getRemoteSocketAddress();

            return context.runtime.newArray(
                socket, Sockaddr.packSockaddrFromAddress(context, addr));
          } finally {
            selectable.configureBlocking(oldBlocking);
          }
        }
      } else {
        throw context.runtime.newErrnoENOPROTOOPTError();
      }
    } catch (IOException e) {
      throw sockerr(context.runtime, e.getLocalizedMessage(), e);
    }
  }