From 36e14568e7cfcb12bcf7bcc04f7a7bfb7c071030 Mon Sep 17 00:00:00 2001 From: Stephen Halter <halter73@gmail.com> Date: Fri, 17 Jun 2022 16:03:35 -0700 Subject: [PATCH] Partition more ConcurrentQueues in Kestrel (#42237) --- .../src/SocketConnectionContextFactory.cs | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionContextFactory.cs b/src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionContextFactory.cs index cd43cb1e7de..11e3aca3125 100644 --- a/src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionContextFactory.cs +++ b/src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionContextFactory.cs @@ -15,7 +15,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets; /// </summary> public sealed class SocketConnectionContextFactory : IDisposable { - private readonly MemoryPool<byte> _memoryPool; private readonly SocketConnectionFactoryOptions _options; private readonly ILogger _logger; private readonly int _settingsCount; @@ -43,7 +42,6 @@ public sealed class SocketConnectionContextFactory : IDisposable _options = options; _logger = logger; - _memoryPool = _options.MemoryPoolFactory(); _settingsCount = _options.IOQueueCount; var maxReadBufferSize = _options.MaxReadBufferSize ?? 0; @@ -56,6 +54,7 @@ public sealed class SocketConnectionContextFactory : IDisposable for (var i = 0; i < _settingsCount; i++) { + var memoryPool = _options.MemoryPoolFactory(); var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : new IOQueue(); // https://github.com/aspnet/KestrelHttpServer/issues/2573 var awaiterScheduler = OperatingSystem.IsWindows() ? transportScheduler : PipeScheduler.Inline; @@ -63,26 +62,29 @@ public sealed class SocketConnectionContextFactory : IDisposable _settings[i] = new QueueSettings() { Scheduler = transportScheduler, - InputOptions = new PipeOptions(_memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false), - OutputOptions = new PipeOptions(_memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false), - SocketSenderPool = new SocketSenderPool(awaiterScheduler) + InputOptions = new PipeOptions(memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false), + OutputOptions = new PipeOptions(memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false), + SocketSenderPool = new SocketSenderPool(awaiterScheduler), + MemoryPool = memoryPool, }; } } else { + var memoryPool = _options.MemoryPoolFactory(); var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : PipeScheduler.ThreadPool; // https://github.com/aspnet/KestrelHttpServer/issues/2573 var awaiterScheduler = OperatingSystem.IsWindows() ? transportScheduler : PipeScheduler.Inline; _settings = new QueueSettings[] { - new QueueSettings() - { - Scheduler = transportScheduler, - InputOptions = new PipeOptions(_memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false), - OutputOptions = new PipeOptions(_memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false), - SocketSenderPool = new SocketSenderPool(awaiterScheduler) - } + new QueueSettings() + { + Scheduler = transportScheduler, + InputOptions = new PipeOptions(memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false), + OutputOptions = new PipeOptions(memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false), + SocketSenderPool = new SocketSenderPool(awaiterScheduler), + MemoryPool = memoryPool, + } }; _settingsCount = 1; } @@ -98,7 +100,7 @@ public sealed class SocketConnectionContextFactory : IDisposable var setting = _settings[Interlocked.Increment(ref _settingsIndex) % _settingsCount]; var connection = new SocketConnection(socket, - _memoryPool, + setting.MemoryPool, setting.Scheduler, _logger, setting.SocketSenderPool, @@ -113,13 +115,11 @@ public sealed class SocketConnectionContextFactory : IDisposable /// <inheritdoc /> public void Dispose() { - // Dispose the memory pool - _memoryPool.Dispose(); - - // Dispose any pooled senders + // Dispose any pooled senders and memory pools foreach (var setting in _settings) { setting.SocketSenderPool.Dispose(); + setting.MemoryPool.Dispose(); } } @@ -129,5 +129,6 @@ public sealed class SocketConnectionContextFactory : IDisposable public PipeOptions InputOptions { get; init; } = default!; public PipeOptions OutputOptions { get; init; } = default!; public SocketSenderPool SocketSenderPool { get; init; } = default!; + public MemoryPool<byte> MemoryPool { get; init; } = default!; } } -- GitLab