Ejemplo n.º 1
0
    @JRubyMethod
    public static IRubyObject rbuf_fill(IRubyObject recv) {
      RubyString buf = (RubyString) recv.getInstanceVariables().getInstanceVariable("@rbuf");
      RubyIO io = (RubyIO) recv.getInstanceVariables().getInstanceVariable("@io");

      int timeout =
          RubyNumeric.fix2int(recv.getInstanceVariables().getInstanceVariable("@read_timeout"))
              * 1000;
      NativeImpl nim = (NativeImpl) recv.dataGetStruct();

      Selector selector = null;
      synchronized (nim.channel.blockingLock()) {
        boolean oldBlocking = nim.channel.isBlocking();

        try {
          selector =
              SelectorFactory.openWithRetryFrom(recv.getRuntime(), SelectorProvider.provider());
          nim.channel.configureBlocking(false);
          SelectionKey key = nim.channel.register(selector, SelectionKey.OP_READ);
          int n = selector.select(timeout);

          if (n > 0) {
            IRubyObject readItems =
                io.read(new IRubyObject[] {recv.getRuntime().newFixnum(1024 * 16)});
            return buf.concat(readItems);
          } else {
            RubyClass exc =
                (RubyClass) (recv.getRuntime().getModule("Timeout").getConstant("Error"));
            throw new RaiseException(
                RubyException.newException(recv.getRuntime(), exc, "execution expired"), false);
          }
        } catch (IOException exception) {
          throw recv.getRuntime().newIOErrorFromException(exception);
        } finally {
          if (selector != null) {
            try {
              selector.close();
            } catch (Exception e) {
            }
          }
          try {
            nim.channel.configureBlocking(oldBlocking);
          } catch (IOException ioe) {
          }
        }
      }
    }