Exemplo n.º 1
0
            public override void FinishRead(SocketChannelAsyncOperation operation)
            {
                AbstractSocketByteChannel ch = this.Channel;

                ch.ResetState(StateFlags.ReadScheduled);
                IChannelConfiguration config            = ch.Configuration;
                IChannelPipeline      pipeline          = ch.Pipeline;
                IByteBufferAllocator  allocator         = config.Allocator;
                int maxMessagesPerRead                  = config.MaxMessagesPerRead;
                IRecvByteBufAllocatorHandle allocHandle = this.RecvBufAllocHandle;

                IByteBuffer byteBuf  = null;
                int         messages = 0;
                bool        close    = false;

                try
                {
                    operation.Validate();

                    int  totalReadAmount  = 0;
                    bool readPendingReset = false;
                    do
                    {
                        byteBuf = allocHandle.Allocate(allocator);
                        int writable        = byteBuf.WritableBytes;
                        int localReadAmount = ch.DoReadBytes(byteBuf);
                        if (localReadAmount <= 0)
                        {
                            // not was read release the buffer
                            byteBuf.Release();
                            byteBuf = null;
                            close   = localReadAmount < 0;
                            break;
                        }
                        if (!readPendingReset)
                        {
                            readPendingReset = true;
                            ch.ReadPending   = false;
                        }
                        pipeline.FireChannelRead(byteBuf);
                        byteBuf = null;

                        if (totalReadAmount >= int.MaxValue - localReadAmount)
                        {
                            // Avoid overflow.
                            totalReadAmount = int.MaxValue;
                            break;
                        }

                        totalReadAmount += localReadAmount;

                        // stop reading
                        if (!config.AutoRead)
                        {
                            break;
                        }

                        if (localReadAmount < writable)
                        {
                            // Read less than what the buffer can hold,
                            // which might mean we drained the recv buffer completely.
                            break;
                        }
                    }while (++messages < maxMessagesPerRead);

                    pipeline.FireChannelReadComplete();
                    allocHandle.Record(totalReadAmount);

                    if (close)
                    {
                        this.CloseOnRead();
                        close = false;
                    }
                }
                catch (Exception t)
                {
                    this.HandleReadException(pipeline, byteBuf, t, close);
                }
                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() input channelRead(...) method
                    // /// The user called Channel.read() or ChannelHandlerContext.read() input channelReadComplete(...) method
                    //
                    // See https://github.com/netty/netty/issues/2254
                    if (!close && (ch.ReadPending || config.AutoRead))
                    {
                        ch.DoBeginRead();
                    }
                }
            }