예제 #1
0
  @Override
  protected void doBeginRead() throws Exception {
    if (readInProgress) {
      return;
    }

    ChannelPipeline pipeline = pipeline();
    Queue<Object> inboundBuffer = this.inboundBuffer;
    if (inboundBuffer.isEmpty()) {
      readInProgress = true;
      return;
    }

    final Integer stackDepth = READER_STACK_DEPTH.get();
    if (stackDepth < MAX_READER_STACK_DEPTH) {
      READER_STACK_DEPTH.set(stackDepth + 1);
      try {
        for (; ; ) {
          Object received = inboundBuffer.poll();
          if (received == null) {
            break;
          }
          pipeline.fireChannelRead(received);
        }
        pipeline.fireChannelReadComplete();
      } finally {
        READER_STACK_DEPTH.set(stackDepth);
      }
    } else {
      eventLoop().execute(readTask);
    }
  }
예제 #2
0
 @Override
 public void run() {
   ChannelPipeline pipeline = pipeline();
   for (; ; ) {
     Object m = inboundBuffer.poll();
     if (m == null) {
       break;
     }
     pipeline.fireChannelRead(m);
   }
   pipeline.fireChannelReadComplete();
 }
예제 #3
0
 private static void finishPeerRead(LocalChannel peer, ChannelPipeline peerPipeline) {
   if (peer.readInProgress) {
     peer.readInProgress = false;
     for (; ; ) {
       Object received = peer.inboundBuffer.poll();
       if (received == null) {
         break;
       }
       peerPipeline.fireChannelRead(received);
     }
     peerPipeline.fireChannelReadComplete();
   }
 }
 private void serve0(final LocalChannel child) {
   inboundBuffer.add(child);
   if (acceptInProgress) {
     acceptInProgress = false;
     ChannelPipeline pipeline = pipeline();
     for (; ; ) {
       Object m = inboundBuffer.poll();
       if (m == null) {
         break;
       }
       pipeline.fireChannelRead(m);
     }
     pipeline.fireChannelReadComplete();
   }
 }
예제 #5
0
 private boolean handleReadException(
     ChannelPipeline pipeline, ByteBuf byteBuf, Throwable cause, boolean close) {
   if (byteBuf != null) {
     if (byteBuf.isReadable()) {
       readPending = false;
       pipeline.fireChannelRead(byteBuf);
     } else {
       byteBuf.release();
     }
   }
   pipeline.fireChannelReadComplete();
   pipeline.fireExceptionCaught(cause);
   if (close || cause instanceof IOException) {
     closeOnRead(pipeline);
     return true;
   }
   return false;
 }
 private void handleReadException(
     ChannelPipeline pipeline, ByteBuf byteBuf, Throwable cause, boolean close) {
   if (byteBuf != null) {
     if (byteBuf.isReadable()) {
       pipeline.fireChannelRead(byteBuf);
     } else {
       try {
         byteBuf.release();
       } catch (IllegalReferenceCountException ignore) {
         // ignore as it may be released already
       }
     }
   }
   pipeline.fireChannelReadComplete();
   pipeline.fireExceptionCaught(cause);
   if (close || cause instanceof IOException) {
     closeOnRead();
   }
 }
    @Override
    public void handleEvent(ConduitStreamSourceChannel channel) {
      final ChannelConfig config = config();
      final ChannelPipeline pipeline = pipeline();
      final ByteBufAllocator allocator = config.getAllocator();
      final int maxMessagesPerRead = config.getMaxMessagesPerRead();
      RecvByteBufAllocator.Handle allocHandle = this.allocHandle;
      if (allocHandle == null) {
        this.allocHandle = allocHandle = config.getRecvByteBufAllocator().newHandle();
      }
      if (!config.isAutoRead()) {
        removeReadOp(channel);
      }

      ByteBuf byteBuf = null;
      int messages = 0;
      boolean close = false;
      try {
        do {
          byteBuf = allocHandle.allocate(allocator);
          int localReadAmount = byteBuf.writeBytes(channel, byteBuf.writableBytes());
          if (localReadAmount <= 0) {
            // not was read release the buffer
            byteBuf.release();
            close = localReadAmount < 0;
            break;
          }
          pipeline.fireChannelRead(byteBuf);
          byteBuf = null;
          allocHandle.record(localReadAmount);
        } while (++messages < maxMessagesPerRead);

        pipeline.fireChannelReadComplete();

        if (close) {
          closeOnRead();
          close = false;
        }
      } catch (Throwable t) {
        handleReadException(pipeline, byteBuf, t, close);
      }
    }
  @Override
  protected void doBeginRead() throws Exception {
    if (acceptInProgress) {
      return;
    }

    Queue<Object> inboundBuffer = this.inboundBuffer;
    if (inboundBuffer.isEmpty()) {
      acceptInProgress = true;
      return;
    }

    ChannelPipeline pipeline = pipeline();
    for (; ; ) {
      Object m = inboundBuffer.poll();
      if (m == null) {
        break;
      }
      pipeline.fireChannelRead(m);
    }
    pipeline.fireChannelReadComplete();
  }
예제 #9
0
    @Override
    void epollInReady() {
      final ChannelConfig config = config();
      final ChannelPipeline pipeline = pipeline();
      final ByteBufAllocator allocator = config.getAllocator();
      RecvByteBufAllocator.Handle allocHandle = this.allocHandle;
      if (allocHandle == null) {
        this.allocHandle = allocHandle = config.getRecvByteBufAllocator().newHandle();
      }

      ByteBuf byteBuf = null;
      boolean close = false;
      try {
        int byteBufCapacity = allocHandle.guess();
        int totalReadAmount = 0;
        for (; ; ) {
          // we use a direct buffer here as the native implementations only be able
          // to handle direct buffers.
          byteBuf = allocator.directBuffer(byteBufCapacity);
          int writable = byteBuf.writableBytes();
          int localReadAmount = doReadBytes(byteBuf);
          if (localReadAmount <= 0) {
            // not was read release the buffer
            byteBuf.release();
            close = localReadAmount < 0;
            break;
          }
          readPending = false;
          pipeline.fireChannelRead(byteBuf);
          byteBuf = null;

          if (totalReadAmount >= Integer.MAX_VALUE - localReadAmount) {
            allocHandle.record(totalReadAmount);

            // Avoid overflow.
            totalReadAmount = localReadAmount;
          } else {
            totalReadAmount += localReadAmount;
          }

          if (localReadAmount < writable) {
            // Read less than what the buffer can hold,
            // which might mean we drained the recv buffer completely.
            break;
          }
        }
        pipeline.fireChannelReadComplete();
        allocHandle.record(totalReadAmount);

        if (close) {
          closeOnRead(pipeline);
          close = false;
        }
      } catch (Throwable t) {
        boolean closed = handleReadException(pipeline, byteBuf, t, close);
        if (!closed) {
          // trigger a read again as there may be something left to read and because of epoll ET we
          // will not get notified again until we read everything from the socket
          eventLoop()
              .execute(
                  new Runnable() {
                    @Override
                    public void run() {
                      epollInReady();
                    }
                  });
        }
      } finally {
        // Check if there is a readPending which was not processed yet.
        // This could be for two reasons:
        // * The user called Channel.read() or ChannelHandlerContext.read() in channelRead(...)
        // method
        // * The user called Channel.read() or ChannelHandlerContext.read() in
        // channelReadComplete(...) method
        //
        // See https://github.com/netty/netty/issues/2254
        if (!config.isAutoRead() && !readPending) {
          clearEpollIn0();
        }
      }
    }