Null out send buffer less (#2164)

This commit is contained in:
Stephen Halter 2017-11-17 12:41:35 -08:00 committed by GitHub
parent 89d1862f21
commit 67fc879c54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 19 additions and 25 deletions

View File

@ -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<ArraySegment<byte>>();
}
// 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);
}
}
}