From dd71863f6f0f762dbe3806b77596a868ffdc51c9 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Mon, 25 May 2020 18:00:57 +0100 Subject: [PATCH] If not waiting for data, allocate memory before flush --- .../src/Internal/SocketConnection.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketConnection.cs b/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketConnection.cs index 4088dab97871..1bb2f832245a 100644 --- a/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketConnection.cs +++ b/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketConnection.cs @@ -187,17 +187,24 @@ private async Task ProcessReceives() { // Resolve `input` PipeWriter via the IDuplexPipe interface prior to loop start for performance. var input = Input; + + Memory buffer = default; + if (!_waitForData) + { + // Ensure we have some reasonable amount of buffer space to start. + buffer = input.GetMemory(MinAllocBufferSize); + } + while (true) { if (_waitForData) { // Wait for data before allocating a buffer. await _receiver.WaitForDataAsync(); + // Data ready, allocate some memory to receive it. + buffer = input.GetMemory(MinAllocBufferSize); } - // Ensure we have some reasonable amount of buffer space - var buffer = input.GetMemory(MinAllocBufferSize); - var bytesReceived = await _receiver.ReceiveAsync(buffer); if (bytesReceived == 0) @@ -209,6 +216,13 @@ private async Task ProcessReceives() input.Advance(bytesReceived); + if (!_waitForData) + { + // If not waiting for data allocate another buffer before flushing, + // to reduce reader/writer contention on MemoryPool. + buffer = input.GetMemory(MinAllocBufferSize); + } + var flushTask = input.FlushAsync(); var paused = !flushTask.IsCompleted;