From 67fc879c548048aa04288be7c313d0ebb92d6bc4 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Fri, 17 Nov 2017 12:41:35 -0800 Subject: [PATCH] Null out send buffer less (#2164) --- .../Internal/SocketSender.cs | 44 ++++++++----------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/Kestrel.Transport.Sockets/Internal/SocketSender.cs b/src/Kestrel.Transport.Sockets/Internal/SocketSender.cs index 0b3b998c6b..365339aa50 100644 --- a/src/Kestrel.Transport.Sockets/Internal/SocketSender.cs +++ b/src/Kestrel.Transport.Sockets/Internal/SocketSender.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal { _socket = socket; _eventArgs.UserToken = _awaitable; - _eventArgs.Completed += (_, e) => SendCompleted(e, (SocketAwaitable)e.UserToken); + _eventArgs.Completed += (_, e) => ((SocketAwaitable)e.UserToken).Complete(e.BytesTransferred, e.SocketError); } public SocketAwaitable SendAsync(ReadableBuffer buffers) @@ -31,11 +31,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal return SendAsync(buffers.First); } + if (_eventArgs.Buffer != null) + { + _eventArgs.SetBuffer(null, 0, 0); + } + _eventArgs.BufferList = GetBufferList(buffers); if (!_socket.SendAsync(_eventArgs)) { - SendCompleted(_eventArgs, _awaitable); + _awaitable.Complete(_eventArgs.BytesTransferred, _eventArgs.SocketError); } return _awaitable; @@ -45,11 +50,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal { var segment = buffer.GetArray(); + // The BufferList getter is much less expensive then the setter. + if (_eventArgs.BufferList != null) + { + _eventArgs.BufferList = null; + } + _eventArgs.SetBuffer(segment.Array, segment.Offset, segment.Count); if (!_socket.SendAsync(_eventArgs)) { - SendCompleted(_eventArgs, _awaitable); + _awaitable.Complete(_eventArgs.BytesTransferred, _eventArgs.SocketError); } return _awaitable; @@ -64,9 +75,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal { _bufferList = new List>(); } - - // We should always clear the list after the send - Debug.Assert(_bufferList.Count == 0); + else + { + // Buffers are pooled, so it's OK to root them until the next multi-buffer write. + _bufferList.Clear(); + } foreach (var b in buffer) { @@ -75,24 +88,5 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal return _bufferList; } - - private static void SendCompleted(SocketAsyncEventArgs e, SocketAwaitable awaitable) - { - // Clear buffer(s) to prevent the SetBuffer buffer and BufferList from both being - // set for the next write operation. This is unnecessary for reads since they never - // set BufferList. - - if (e.BufferList != null) - { - e.BufferList.Clear(); - e.BufferList = null; - } - else - { - e.SetBuffer(null, 0, 0); - } - - awaitable.Complete(e.BytesTransferred, e.SocketError); - } } }