Esempio n. 1
0
  @Override
  protected boolean read(SelectionKey k) {
    final SocketChannel ch = (SocketChannel) k.channel();
    final NioSocketChannel channel = (NioSocketChannel) k.attachment();

    final ReceiveBufferSizePredictor predictor =
        channel.getConfig().getReceiveBufferSizePredictor();
    final int predictedRecvBufSize = predictor.nextReceiveBufferSize();

    int ret = 0;
    int readBytes = 0;
    boolean failure = true;

    ByteBuffer bb = recvBufferPool.acquire(predictedRecvBufSize);
    try {
      while ((ret = ch.read(bb)) > 0) {
        readBytes += ret;
        if (!bb.hasRemaining()) {
          break;
        }
      }
      failure = false;
    } catch (ClosedChannelException e) {
      // Can happen, and does not need a user attention.
    } catch (Throwable t) {
      fireExceptionCaught(channel, t);
    }

    if (readBytes > 0) {
      bb.flip();

      final ChannelBufferFactory bufferFactory = channel.getConfig().getBufferFactory();
      final ChannelBuffer buffer = bufferFactory.getBuffer(readBytes);
      buffer.setBytes(0, bb);
      buffer.writerIndex(readBytes);

      recvBufferPool.release(bb);

      // Update the predictor.
      predictor.previousReceiveBufferSize(readBytes);

      // Fire the event.
      fireMessageReceived(channel, buffer);
    } else {
      recvBufferPool.release(bb);
    }

    if (ret < 0 || failure) {
      k.cancel(); // Some JDK implementations run into an infinite loop without this.
      close(channel, succeededFuture(channel));
      return false;
    }

    return true;
  }
Esempio n. 2
0
  public void run() {
    channel.workerThread = Thread.currentThread();
    final MulticastSocket socket = channel.socket;

    while (channel.isOpen()) {
      synchronized (channel.interestOpsLock) {
        while (!channel.isReadable()) {
          try {
            // notify() is not called at all.
            // close() and setInterestOps() calls Thread.interrupt()
            channel.interestOpsLock.wait();
          } catch (InterruptedException e) {
            if (!channel.isOpen()) {
              break;
            }
          }
        }
      }

      ReceiveBufferSizePredictor predictor = channel.getConfig().getReceiveBufferSizePredictor();

      byte[] buf = new byte[predictor.nextReceiveBufferSize()];
      DatagramPacket packet = new DatagramPacket(buf, buf.length);
      try {
        socket.receive(packet);
      } catch (InterruptedIOException e) {
        // Can happen on interruption.
        // Keep receiving unless the channel is closed.
        continue;
      } catch (Throwable t) {
        if (!channel.socket.isClosed()) {
          fireExceptionCaught(channel, t);
        }
        break;
      }

      fireMessageReceived(
          channel,
          channel.getConfig().getBufferFactory().getBuffer(buf, 0, packet.getLength()),
          packet.getSocketAddress());
    }

    // Setting the workerThread to null will prevent any channel
    // operations from interrupting this thread from now on.
    channel.workerThread = null;

    // Clean up.
    close(channel, succeededFuture(channel));
  }
Esempio n. 3
0
  private static boolean read(SelectionKey k) {
    ScatteringByteChannel ch = (ScatteringByteChannel) k.channel();
    NioSocketChannel channel = (NioSocketChannel) k.attachment();

    ReceiveBufferSizePredictor predictor = channel.getConfig().getReceiveBufferSizePredictor();
    ChannelBufferFactory bufferFactory = channel.getConfig().getBufferFactory();

    ChannelBuffer buffer = bufferFactory.getBuffer(predictor.nextReceiveBufferSize());

    int ret = 0;
    int readBytes = 0;
    boolean failure = true;
    try {
      while ((ret = buffer.writeBytes(ch, buffer.writableBytes())) > 0) {
        readBytes += ret;
        if (!buffer.writable()) {
          break;
        }
      }
      failure = false;
    } catch (AsynchronousCloseException e) {
      // Can happen, and does not need a user attention.
    } catch (Throwable t) {
      fireExceptionCaught(channel, t);
    }

    if (readBytes > 0) {
      // Update the predictor.
      predictor.previousReceiveBufferSize(readBytes);

      // Fire the event.
      fireMessageReceived(channel, buffer);
    }

    if (ret < 0 || failure) {
      close(k);
      return false;
    }

    return true;
  }