public SocketMessageUnsafe(AbstractSocketMessageChannel channel)
     : base(channel)
 {
 }
 public SocketMessageUnsafe(AbstractSocketMessageChannel channel)
     : base(channel)
 {
 }
            public override void FinishRead(SocketChannelAsyncOperation operation)
            {
                Contract.Requires(this.channel.EventLoop.InEventLoop);
                AbstractSocketMessageChannel ch = this.Channel;

                ch.ResetState(StateFlags.ReadScheduled);
                IChannelConfiguration config = ch.Configuration;

                if (!config.AutoRead && !ch.ReadPending)
                {
                    // ChannelConfig.setAutoRead(false) was called in the meantime
                    //removeReadOp(); -- noop with IOCP, just don't schedule receive again
                    return;
                }

                int maxMessagesPerRead     = config.MaxMessagesPerRead;
                IChannelPipeline pipeline  = ch.Pipeline;
                bool             closed    = false;
                Exception        exception = null;

                try
                {
                    try
                    {
                        while (true)
                        {
                            int localRead = ch.DoReadMessages(this.readBuf);
                            if (localRead == 0)
                            {
                                break;
                            }
                            if (localRead < 0)
                            {
                                closed = true;
                                break;
                            }

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

                            if (this.readBuf.Count >= maxMessagesPerRead)
                            {
                                break;
                            }
                        }
                    }
                    catch (Exception t)
                    {
                        exception = t;
                    }
                    ch.ReadPending = false;
                    int size = this.readBuf.Count;
                    for (int i = 0; i < size; i++)
                    {
                        pipeline.FireChannelRead(this.readBuf[i]);
                    }

                    this.readBuf.Clear();
                    pipeline.FireChannelReadComplete();

                    if (exception != null)
                    {
                        var asSocketException = exception as SocketException;
                        if (asSocketException != null && asSocketException.SocketErrorCode != SocketError.TryAgain) // todo: other conditions for not closing message-based socket?
                        {
                            // ServerChannel should not be closed even on SocketException because it can often continue
                            // accepting incoming connections. (e.g. too many open files)
                            closed = !(ch is IServerChannel);
                        }

                        pipeline.FireExceptionCaught(exception);
                    }

                    if (closed)
                    {
                        if (ch.Open)
                        {
                            this.CloseAsync();
                        }
                    }
                }
                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 (!closed && (config.AutoRead || ch.ReadPending))
                    {
                        ch.DoBeginRead();
                    }
                }
            }
Beispiel #4
0
            public override void FinishRead(SocketChannelAsyncOperation operation)
            {
                Contract.Assert(this.channel.EventLoop.InEventLoop);

                AbstractSocketMessageChannel ch = this.Channel;

                if ((ch.ResetState(StateFlags.ReadScheduled) & StateFlags.Active) == 0)
                {
                    return; // read was signaled as a result of channel closure
                }
                IChannelConfiguration config = ch.Configuration;

                IChannelPipeline            pipeline    = ch.Pipeline;
                IRecvByteBufAllocatorHandle allocHandle = this.Channel.Unsafe.RecvBufAllocHandle;

                allocHandle.Reset(config);

                bool      closed    = false;
                Exception exception = null;

                try
                {
                    try
                    {
                        do
                        {
                            int localRead = ch.DoReadMessages(this.readBuf);
                            if (localRead == 0)
                            {
                                break;
                            }
                            if (localRead < 0)
                            {
                                closed = true;
                                break;
                            }

                            allocHandle.IncMessagesRead(localRead);
                        }while (allocHandle.ContinueReading());
                    }
                    catch (Exception t)
                    {
                        exception = t;
                    }
                    int size = this.readBuf.Count;
                    for (int i = 0; i < size; i++)
                    {
                        ch.ReadPending = false;
                        pipeline.FireChannelRead(this.readBuf[i]);
                    }

                    this.readBuf.Clear();
                    allocHandle.ReadComplete();
                    pipeline.FireChannelReadComplete();

                    if (exception != null)
                    {
                        var asSocketException = exception as SocketException;
                        if (asSocketException != null && asSocketException.SocketErrorCode != SocketError.TryAgain) // todo: other conditions for not closing message-based socket?
                        {
                            // ServerChannel should not be closed even on SocketException because it can often continue
                            // accepting incoming connections. (e.g. too many open files)
                            closed = !(ch is IServerChannel);
                        }

                        pipeline.FireExceptionCaught(exception);
                    }

                    if (closed)
                    {
                        if (ch.Open)
                        {
                            this.CloseSafe();
                        }
                    }
                }
                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 (!closed && (ch.ReadPending || config.AutoRead))
                    {
                        ch.DoBeginRead();
                    }
                }
            }