public void FinishWrite(SocketChannelAsyncOperation operation) { bool resetWritePending = this.Channel.ResetState(StateFlags.WriteScheduled); Contract.Assert(resetWritePending); var input = OutboundBuffer; try { operation.Validate(); var sent = operation.BytesTransferred; Channel.ResetWriteOperation(); if (sent > 0) { input.RemoveBytes(sent); } } catch (Exception ex) { input.FailFlushed(ex, true); throw; } // directly call super.flush0() to force a flush now base.Flush0(); }
public void FinishWrite(SocketChannelAsyncOperation operation) { var input = OutboundBuffer; try { operation.Validate(); var sent = operation.BytesTransferred; Channel.ResetWriteOperation(); if (sent > 0) { var msg = input.Current; var buffer = msg as IByteBuf; if (buffer != null) { buffer.SetWriterIndex(buffer.WriterIndex + sent); } // todo: FileRegion support } } catch (Exception ex) { input.FailFlushed(ex, true); throw; } // directly call super.flush0() to force a flush now base.Flush0(); }
protected override void DoFinishConnect(SocketChannelAsyncOperation operation) { try { operation.Validate(); } finally { operation.Dispose(); } OnConnected(); }
public override void FinishRead(SocketChannelAsyncOperation operation) { var ch = Channel; ch.ResetState(StateFlags.ReadScheduled); var 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; } var pipeline = ch.Pipeline; var allocator = config.Allocator; var maxMessagesPerRead = config.MaxMessagesPerRead; var allocHandle = RecvBufAllocHandle; IByteBuf byteBuf = null; var messages = 0; var close = false; try { operation.Validate(); var totalReadAmount = 0; var readPendingReset = false; do { byteBuf = allocHandle.Allocate(allocator); var writable = byteBuf.WritableBytes; var 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) { CloseOnRead(); close = false; } } catch (Exception t) { 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 && (config.AutoRead || ch.ReadPending)) { ch.DoBeginRead(); } } }
public override void FinishRead(SocketChannelAsyncOperation operation) { Contract.Requires(this._channel.EventLoop.InEventLoop); TcpServerSocketChannel ch = this.Channel; ch.ResetState(StateFlags.ReadScheduled); IChannelConfiguration config = ch.Configuration; int maxMessagesPerRead = config.MaxMessagesPerRead; IChannelPipeline pipeline = ch.Pipeline; bool closed = false; Exception exception = null; int messageCount = 0; try { Socket connectedSocket = null; try { connectedSocket = operation.AcceptSocket; operation.Validate(); operation.AcceptSocket = null; var message = new TcpSocketChannel(ch, connectedSocket, true); ch.ReadPending = false; pipeline.FireChannelRead(message); messageCount++; if (!config.AutoRead && !ch.ReadPending) { // ChannelConfig.setAutoRead(false) was called in the meantime. // Completed Accept has to be processed though. return; } while (messageCount < maxMessagesPerRead) { connectedSocket = null; connectedSocket = ch.Socket.Accept(); message = new TcpSocketChannel(ch, connectedSocket, true); pipeline.FireChannelRead(message); // stop reading and remove op if (!config.AutoRead) { break; } messageCount++; } } catch (ObjectDisposedException) { closed = true; } catch (Exception ex) { var asSocketException = ex as SocketException; if (asSocketException == null || asSocketException.SocketErrorCode != SocketError.WouldBlock) { Logger.Warning(ex, "Failed to create a new channel from an accepted socket."); if (connectedSocket != null) { try { connectedSocket.Close(); } catch (Exception ex2) { Logger.Warning(ex2, "Failed to close a socket."); } } exception = ex; } } pipeline.FireChannelReadComplete(); if (exception != null) { // ServerChannel should not be closed even on SocketException because it can often continue // accepting incoming connections. (e.g. too many open files) pipeline.FireExceptionCaught(exception); } if (closed) { if (ch.IsOpen) { this.CloseAsync(); } } } finally { // Check if there is a readPending which was not processed yet. if (!closed && (config.AutoRead || ch.ReadPending)) { ch.DoBeginRead(); } } }
public override void FinishRead(SocketChannelAsyncOperation operation) { var ch = Channel; ch.ResetState(StateFlags.ReadScheduled); var config = ch.Configuration; var pipeline = ch.Pipeline; var allocator = config.Allocator; var maxMessagesPerRead = config.MaxMessagesPerRead; var allocHandle = RecvBufAllocHandle; IByteBuf byteBuf = null; var messages = 0; var close = false; try { operation.Validate(); var totalReadAmount = 0; var readPendingReset = false; do { byteBuf = allocHandle.Allocate(allocator); var writable = byteBuf.WritableBytes; var 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) { CloseOnRead(); close = false; } } catch (Exception t) { 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(); } } }