public override void FinishRead(SocketChannelAsyncOperation <TChannel, TUnsafe> operation)
            {
                var ch = _channel;

                if (0u >= (uint)(ch.ResetState(StateFlags.ReadScheduled) & StateFlags.Active))
                {
                    return; // read was signaled as a result of channel closure
                }
                IChannelConfiguration       config      = ch.Configuration;
                IChannelPipeline            pipeline    = ch.Pipeline;
                IByteBufferAllocator        allocator   = config.Allocator;
                IRecvByteBufAllocatorHandle allocHandle = RecvBufAllocHandle;

                allocHandle.Reset(config);

                IByteBuffer byteBuf = null;
                bool        close   = false;

                try
                {
                    operation.Validate();

                    do
                    {
                        byteBuf = allocHandle.Allocate(allocator);
                        //int writable = byteBuf.WritableBytes;
                        allocHandle.LastBytesRead = ch.DoReadBytes(byteBuf);
                        if (allocHandle.LastBytesRead <= 0)
                        {
                            // nothing was read -> release the buffer.
                            _       = byteBuf.Release();
                            byteBuf = null;
                            close   = allocHandle.LastBytesRead < 0;
                            if (close)
                            {
                                // There is nothing left to read as we received an EOF.
                                ch.ReadPending = false;
                            }
                            break;
                        }

                        allocHandle.IncMessagesRead(1);
                        ch.ReadPending = false;

                        _       = pipeline.FireChannelRead(byteBuf);
                        byteBuf = null;
                    }while (allocHandle.ContinueReading());

                    allocHandle.ReadComplete();
                    _ = pipeline.FireChannelReadComplete();

                    if (close)
                    {
                        CloseOnRead();
                    }
                }
                catch (Exception t)
                {
                    HandleReadException(pipeline, byteBuf, t, close, allocHandle);
                }
                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();
                    }
                }
            }
Esempio n. 2
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();
                    }
                }
            }
Esempio n. 3
0
        /// <summary>
        /// ScheduleAsync a read operation.
        /// </summary>
        protected override async void DoBeginRead()
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, nameof(DoBeginRead));
            }

            try
            {
                IByteBuffer byteBuffer = null;
                IRecvByteBufAllocatorHandle allocHandle = null;
                bool close = false;
                try
                {
                    if (!Open || _isReadPending)
                    {
                        return;
                    }

                    _isReadPending = true;
                    IByteBufferAllocator allocator = Configuration.Allocator;
                    allocHandle = Configuration.RecvByteBufAllocator.NewHandle();
                    allocHandle.Reset(Configuration);
                    do
                    {
                        byteBuffer = allocHandle.Allocate(allocator);
                        allocHandle.LastBytesRead = await DoReadBytesAsync(byteBuffer).ConfigureAwait(false);

                        if (allocHandle.LastBytesRead <= 0)
                        {
                            // nothing was read -> release the buffer.
                            byteBuffer.Release();
                            byteBuffer = null;
                            close      = allocHandle.LastBytesRead < 0;
                            break;
                        }

                        Pipeline.FireChannelRead(byteBuffer);
                        allocHandle.IncMessagesRead(1);
                    } while (allocHandle.ContinueReading());

                    allocHandle.ReadComplete();
                    _isReadPending = false;
                    Pipeline.FireChannelReadComplete();
                }
                catch (Exception e) when(!e.IsFatal())
                {
                    // Since this method returns void, all exceptions must be handled here.
                    byteBuffer?.Release();
                    allocHandle?.ReadComplete();
                    _isReadPending = false;
                    Pipeline.FireChannelReadComplete();
                    Pipeline.FireExceptionCaught(e);
                    close = true;
                }

                if (close)
                {
                    if (Active)
                    {
                        await HandleCloseAsync().ConfigureAwait(false);
                    }
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, nameof(DoBeginRead));
                }
            }
        }
Esempio n. 4
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;
                IRecvByteBufAllocatorHandle allocHandle = this.RecvBufAllocHandle;

                allocHandle.Reset(config);

                IByteBuffer byteBuf = null;
                bool        close   = false;

                try
                {
                    operation.Validate();

                    do
                    {
                        byteBuf = allocHandle.Allocate(allocator);
                        //int writable = byteBuf.WritableBytes;
                        allocHandle.LastBytesRead = ch.DoReadBytes(byteBuf);
                        if (allocHandle.LastBytesRead <= 0)
                        {
                            // nothing was read -> release the buffer.
                            byteBuf.Release();
                            byteBuf = null;
                            close   = allocHandle.LastBytesRead < 0;
                            break;
                        }

                        allocHandle.IncMessagesRead(1);
                        this.Channel.ReadPending = false;

                        pipeline.FireChannelRead(byteBuf);
                        byteBuf = null;
                    }while (allocHandle.ContinueReading());

                    allocHandle.ReadComplete();
                    pipeline.FireChannelReadComplete();

                    if (close)
                    {
                        this.CloseOnRead();
                    }
                }
                catch (Exception t)
                {
                    this.HandleReadException(pipeline, byteBuf, t, close, allocHandle);
                }
                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();
                    }
                }
            }
        protected override async void DoBeginRead()
        {
            IByteBuffer byteBuffer = null;
            IRecvByteBufAllocatorHandle allocHandle = null;
            bool close = false;

            try
            {
                if (!this.Open || this.ReadPending)
                {
                    return;
                }

                this.ReadPending = true;
                IByteBufferAllocator allocator = this.Configuration.Allocator;
                allocHandle = this.Configuration.RecvByteBufAllocator.NewHandle();
                allocHandle.Reset(this.Configuration);
                do
                {
                    byteBuffer = allocHandle.Allocate(allocator);
                    allocHandle.LastBytesRead = await this.DoReadBytes(byteBuffer);

                    if (allocHandle.LastBytesRead <= 0)
                    {
                        // nothing was read -> release the buffer.
                        byteBuffer.Release();
                        byteBuffer = null;
                        close      = allocHandle.LastBytesRead < 0;
                        break;
                    }

                    this.Pipeline.FireChannelRead(byteBuffer);
                    allocHandle.IncMessagesRead(1);
                }while (allocHandle.ContinueReading());

                allocHandle.ReadComplete();
                this.ReadPending = false;
                this.Pipeline.FireChannelReadComplete();
            }
            catch (Exception e) when(!e.IsFatal())
            {
                Events.ReadException(this.correlationId, e);

                // Since this method returns void, all exceptions must be handled here.
                byteBuffer.SafeRelease();
                allocHandle?.ReadComplete();
                this.ReadPending = false;

                // WebSocket should change its state when an exception is thrown,
                // but it doesn't (see https://github.com/dotnet/corefx/issues/26219)
                // so we'll abort the connection here.
                this.Abort();

                this.Pipeline.FireChannelReadComplete();
                this.Pipeline.FireExceptionCaught(e);
                close = true;
            }

            if (close)
            {
                if (this.Active)
                {
                    await this.HandleCloseAsync();
                }
            }
        }