@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); } }
@Override public void run() { ChannelPipeline pipeline = pipeline(); for (; ; ) { Object m = inboundBuffer.poll(); if (m == null) { break; } pipeline.fireChannelRead(m); } pipeline.fireChannelReadComplete(); }
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(); } }
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(); }
@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(); } } }