From 0e7967a7fcf932724ec43ed883ff86786aad8409 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 15 Jul 2016 00:48:01 -0700 Subject: [PATCH] Allocate things per KestrelThread instead of per listener - Moved things that have loop affinity to KestrelThread like WriteReqPool, MemoryPool and the ConnectionManager - Changed on the listeners to only kill the ListenSocket, not the connections on dispose - Moved connection disposal to KestrelThread.Stop - Simplify the connection manager logic so it's possible to walk and wait in a single call --- .../Internal/Http/Connection.cs | 6 +- .../Internal/Http/ConnectionManager.cs | 40 +++++----- .../Internal/Http/Listener.cs | 18 +---- .../Internal/Http/ListenerContext.cs | 12 --- .../Internal/Http/ListenerSecondary.cs | 17 ----- .../Internal/Http/SocketOutput.cs | 31 ++------ .../Internal/Infrastructure/KestrelThread.cs | 44 +++++++++++ .../Internal/Infrastructure/WriteReqPool.cs | 73 +++++++++++++++++++ .../ConnectionTests.cs | 2 - .../SocketOutputTests.cs | 35 +++------ 10 files changed, 161 insertions(+), 117 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.Kestrel/Internal/Infrastructure/WriteReqPool.cs diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Connection.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Connection.cs index 0976a37746..0c73c35c7c 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Connection.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Connection.cs @@ -52,8 +52,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http _bufferSizeControl = new BufferSizeControl(ServerOptions.MaxRequestBufferSize.Value, this, Thread); } - SocketInput = new SocketInput(Memory, ThreadPool, _bufferSizeControl); - SocketOutput = new SocketOutput(Thread, _socket, Memory, this, ConnectionId, Log, ThreadPool, WriteReqPool); + SocketInput = new SocketInput(Thread.Memory, ThreadPool, _bufferSizeControl); + SocketOutput = new SocketOutput(Thread, _socket, this, ConnectionId, Log, ThreadPool); var tcpHandle = _socket as UvTcpHandle; if (tcpHandle != null) @@ -166,7 +166,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http { if (_filterContext.Connection != _libuvStream) { - _filteredStreamAdapter = new FilteredStreamAdapter(ConnectionId, _filterContext.Connection, Memory, Log, ThreadPool, _bufferSizeControl); + _filteredStreamAdapter = new FilteredStreamAdapter(ConnectionId, _filterContext.Connection, Thread.Memory, Log, ThreadPool, _bufferSizeControl); _frame.SocketInput = _filteredStreamAdapter.SocketInput; _frame.SocketOutput = _filteredStreamAdapter.SocketOutput; diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ConnectionManager.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ConnectionManager.cs index f546a6c87e..a936855a09 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ConnectionManager.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ConnectionManager.cs @@ -3,30 +3,36 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.Internal.Networking; namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http { public class ConnectionManager { - private KestrelThread _thread; - private List _connectionStopTasks; + private readonly KestrelThread _thread; + private readonly IThreadPool _threadPool; - public ConnectionManager(KestrelThread thread) + public ConnectionManager(KestrelThread thread, IThreadPool threadPool) { _thread = thread; + _threadPool = threadPool; } - // This must be called on the libuv event loop - public void WalkConnectionsAndClose() + public bool WalkConnectionsAndClose(TimeSpan timeout) { - if (_connectionStopTasks != null) - { - throw new InvalidOperationException($"{nameof(WalkConnectionsAndClose)} cannot be called twice."); - } + var wh = new ManualResetEventSlim(); - _connectionStopTasks = new List(); + _thread.Post(state => ((ConnectionManager)state).WalkConnectionsAndCloseCore(wh), this); + + return wh.Wait(timeout); + } + + private void WalkConnectionsAndCloseCore(ManualResetEventSlim wh) + { + var connectionStopTasks = new List(); _thread.Walk(ptr => { @@ -35,19 +41,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http if (connection != null) { - _connectionStopTasks.Add(connection.StopAsync()); + connectionStopTasks.Add(connection.StopAsync()); } }); - } - public Task WaitForConnectionCloseAsync() - { - if (_connectionStopTasks == null) + _threadPool.Run(() => { - throw new InvalidOperationException($"{nameof(WalkConnectionsAndClose)} must be called first."); - } - - return Task.WhenAll(_connectionStopTasks); + Task.WaitAll(connectionStopTasks.ToArray()); + wh.Set(); + }); } } } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Listener.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Listener.cs index a44c1b87bf..abd9c46216 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Listener.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Listener.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http { private bool _closed; - protected Listener(ServiceContext serviceContext) + protected Listener(ServiceContext serviceContext) : base(serviceContext) { } @@ -28,7 +28,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http { ServerAddress = address; Thread = thread; - ConnectionManager = new ConnectionManager(thread); var tcs = new TaskCompletionSource(this); @@ -57,7 +56,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http protected static void ConnectionCallback(UvStreamHandle stream, int status, Exception error, object state) { - var listener = (Listener) state; + var listener = (Listener)state; if (error != null) { @@ -97,22 +96,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http listener._closed = true; - listener.ConnectionManager.WalkConnectionsAndClose(); - }, this).ConfigureAwait(false); - - await ConnectionManager.WaitForConnectionCloseAsync().ConfigureAwait(false); - - await Thread.PostAsync(state => - { - var writeReqPool = ((Listener)state).WriteReqPool; - while (writeReqPool.Count > 0) - { - writeReqPool.Dequeue().Dispose(); - } }, this).ConfigureAwait(false); } - Memory.Dispose(); ListenSocket = null; } } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ListenerContext.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ListenerContext.cs index 83e9956e48..f7c0dd1dac 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ListenerContext.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ListenerContext.cs @@ -16,8 +16,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http public ListenerContext(ServiceContext serviceContext) : base(serviceContext) { - Memory = new MemoryPool(); - WriteReqPool = new Queue(SocketOutput.MaxPooledWriteReqs); } public ListenerContext(ListenerContext listenerContext) @@ -25,20 +23,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http { ServerAddress = listenerContext.ServerAddress; Thread = listenerContext.Thread; - Memory = listenerContext.Memory; - ConnectionManager = listenerContext.ConnectionManager; - WriteReqPool = listenerContext.WriteReqPool; - Log = listenerContext.Log; } public ServerAddress ServerAddress { get; set; } public KestrelThread Thread { get; set; } - - public MemoryPool Memory { get; set; } - - public ConnectionManager ConnectionManager { get; set; } - - public Queue WriteReqPool { get; set; } } } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ListenerSecondary.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ListenerSecondary.cs index e11729200f..f3acef1f1d 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ListenerSecondary.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/ListenerSecondary.cs @@ -39,8 +39,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http ServerAddress = address; Thread = thread; - ConnectionManager = new ConnectionManager(thread); - DispatchPipe = new UvPipeHandle(Log); var tcs = new TaskCompletionSource(this); @@ -180,27 +178,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http listener._closed = true; - listener.ConnectionManager.WalkConnectionsAndClose(); - }, this).ConfigureAwait(false); - - await ConnectionManager.WaitForConnectionCloseAsync().ConfigureAwait(false); - - await Thread.PostAsync(state => - { - var listener = (ListenerSecondary)state; - var writeReqPool = listener.WriteReqPool; - while (writeReqPool.Count > 0) - { - writeReqPool.Dequeue().Dispose(); - } }, this).ConfigureAwait(false); } else { FreeBuffer(); } - - Memory.Dispose(); } } } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/SocketOutput.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/SocketOutput.cs index 7c6be2e7b0..daed0694e5 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/SocketOutput.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/SocketOutput.cs @@ -14,8 +14,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http { public class SocketOutput : ISocketOutput { - public const int MaxPooledWriteReqs = 1024; - private const int _maxPendingWrites = 3; private const int _maxBytesPreCompleted = 65536; // Well behaved WriteAsync users should await returned task, so there is no need to allocate more per connection by default @@ -58,17 +56,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http private WriteContext _nextWriteContext; private readonly Queue _tasksPending; private readonly Queue _writeContextPool; - private readonly Queue _writeReqPool; + private readonly WriteReqPool _writeReqPool; public SocketOutput( KestrelThread thread, UvStreamHandle socket, - MemoryPool memory, Connection connection, string connectionId, IKestrelTrace log, - IThreadPool threadPool, - Queue writeReqPool) + IThreadPool threadPool) { _thread = thread; _socket = socket; @@ -78,9 +74,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http _threadPool = threadPool; _tasksPending = new Queue(_initialTaskQueues); _writeContextPool = new Queue(_maxPooledWriteContexts); - _writeReqPool = writeReqPool; + _writeReqPool = thread.WriteReqPool; - _head = memory.Lease(); + _head = thread.Memory.Lease(); _tail = _head; } @@ -585,15 +581,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http var lockedEndBlock = _lockedEnd.Block; var lockedEndIndex = _lockedEnd.Index; - if (Self._writeReqPool.Count > 0) - { - _writeReq = Self._writeReqPool.Dequeue(); - } - else - { - _writeReq = new UvWriteReq(Self._log); - _writeReq.Init(Self._thread.Loop); - } + _writeReq = Self._writeReqPool.Allocate(); _writeReq.Write(Self._socket, _lockedStart, _lockedEnd, _bufferCount, (_writeReq, status, error, state) => { @@ -691,14 +679,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http private void PoolWriteReq(UvWriteReq writeReq) { - if (Self._writeReqPool.Count < MaxPooledWriteReqs) - { - Self._writeReqPool.Enqueue(writeReq); - } - else - { - writeReq.Dispose(); - } + Self._writeReqPool.Return(writeReq); } private void ScheduleReturnFullyWrittenBlocks() diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Infrastructure/KestrelThread.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Infrastructure/KestrelThread.cs index 3813d75980..47f56ef229 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Infrastructure/KestrelThread.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Infrastructure/KestrelThread.cs @@ -7,6 +7,7 @@ using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.Internal.Networking; using Microsoft.Extensions.Logging; @@ -42,6 +43,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal private ExceptionDispatchInfo _closeError; private readonly IKestrelTrace _log; private readonly IThreadPool _threadPool; + private readonly TimeSpan _shutdownTimeout; public KestrelThread(KestrelEngine engine) { @@ -49,6 +51,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal _appLifetime = engine.AppLifetime; _log = engine.Log; _threadPool = engine.ThreadPool; + _shutdownTimeout = engine.ServerOptions.ShutdownTimeout; _loop = new UvLoopHandle(_log); _post = new UvAsyncHandle(_log); _thread = new Thread(ThreadStart); @@ -60,10 +63,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal #endif QueueCloseHandle = PostCloseHandle; QueueCloseAsyncHandle = EnqueueCloseHandle; + Memory = new MemoryPool(); + WriteReqPool = new WriteReqPool(this, _log); + ConnectionManager = new ConnectionManager(this, _threadPool); } public UvLoopHandle Loop { get { return _loop; } } + public MemoryPool Memory { get; } + + public ConnectionManager ConnectionManager { get; } + + public WriteReqPool WriteReqPool { get; } + public ExceptionDispatchInfo FatalError { get { return _closeError; } } public Action, IntPtr> QueueCloseHandle { get; } @@ -95,6 +107,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal if (_thread.IsAlive) { + // These operations need to run on the libuv thread so it only makes + // sense to attempt execution if it's still running + DisposeConnections(); + var stepTimeout = (int)(timeout.TotalMilliseconds / 2); try { @@ -125,6 +141,34 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal } } + private void DisposeConnections() + { + try + { + // Close and wait for all connections + if (!ConnectionManager.WalkConnectionsAndClose(_shutdownTimeout)) + { + _log.LogError(0, null, "Waiting for connections timed out"); + } + + var result = PostAsync(state => + { + var listener = (KestrelThread)state; + listener.WriteReqPool.Dispose(); + }, + this).Wait(_shutdownTimeout); + + if (!result) + { + _log.LogError(0, null, "Disposing write requests failed"); + } + } + finally + { + Memory.Dispose(); + } + } + private void OnStopRude() { Walk(ptr => diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Infrastructure/WriteReqPool.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Infrastructure/WriteReqPool.cs new file mode 100644 index 0000000000..1f89ec17e2 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Infrastructure/WriteReqPool.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using Microsoft.AspNetCore.Server.Kestrel.Internal.Networking; + +namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure +{ + public class WriteReqPool + { + private const int _maxPooledWriteReqs = 1024; + + private readonly KestrelThread _thread; + private readonly Queue _pool = new Queue(_maxPooledWriteReqs); + private readonly IKestrelTrace _log; + private bool _disposed; + + public WriteReqPool(KestrelThread thread, IKestrelTrace log) + { + _thread = thread; + _log = log; + } + + public UvWriteReq Allocate() + { + if (_disposed) + { + throw new ObjectDisposedException(GetType().Name); + } + + UvWriteReq req; + if (_pool.Count > 0) + { + req = _pool.Dequeue(); + } + else + { + req = new UvWriteReq(_log); + req.Init(_thread.Loop); + } + + return req; + } + + public void Return(UvWriteReq req) + { + if (_disposed) + { + throw new ObjectDisposedException(GetType().Name); + } + + if (_pool.Count < _maxPooledWriteReqs) + { + _pool.Enqueue(req); + } + else + { + req.Dispose(); + } + } + + public void Dispose() + { + if (!_disposed) + { + _disposed = true; + + while (_pool.Count > 0) + { + _pool.Dequeue().Dispose(); + } + } + } + } +} diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/ConnectionTests.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/ConnectionTests.cs index 261bb47068..cdcacc071c 100644 --- a/test/Microsoft.AspNetCore.Server.KestrelTests/ConnectionTests.cs +++ b/test/Microsoft.AspNetCore.Server.KestrelTests/ConnectionTests.cs @@ -17,7 +17,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests { var mockLibuv = new MockLibuv(); - using (var memory = new MemoryPool()) using (var engine = new KestrelEngine(mockLibuv, new TestServiceContext())) { engine.Start(count: 1); @@ -27,7 +26,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests { FrameFactory = connectionContext => new Frame( new DummyApplication(httpContext => TaskUtilities.CompletedTask), connectionContext), - Memory = memory, ServerAddress = ServerAddress.FromUrl("http://127.0.0.1:0"), Thread = engine.Threads[0] }; diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/SocketOutputTests.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/SocketOutputTests.cs index ff26864bc5..c6cd758d1d 100644 --- a/test/Microsoft.AspNetCore.Server.KestrelTests/SocketOutputTests.cs +++ b/test/Microsoft.AspNetCore.Server.KestrelTests/SocketOutputTests.cs @@ -26,8 +26,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests // Arrange var mockLibuv = new MockLibuv(); - - using (var memory = new MemoryPool()) using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext())) { kestrelEngine.Start(count: 1); @@ -36,7 +34,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests var socket = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace()); var trace = new KestrelTrace(new TestKestrelTrace()); var ltp = new LoggingThreadPool(trace); - var socketOutput = new SocketOutput(kestrelThread, socket, memory, new MockConnection(), "0", trace, ltp, new Queue()); + var socketOutput = new SocketOutput(kestrelThread, socket, new MockConnection(), "0", trace, ltp); // I doubt _maxBytesPreCompleted will ever be over a MB. If it is, we should change this test. var bufferSize = 1048576; @@ -78,7 +76,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests } }; - using (var memory = new MemoryPool()) using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext())) { kestrelEngine.Start(count: 1); @@ -88,7 +85,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests var trace = new KestrelTrace(new TestKestrelTrace()); var ltp = new LoggingThreadPool(trace); var mockConnection = new MockConnection(); - var socketOutput = new SocketOutput(kestrelThread, socket, memory, mockConnection, "0", trace, ltp, new Queue()); + var socketOutput = new SocketOutput(kestrelThread, socket, mockConnection, "0", trace, ltp); var bufferSize = maxBytesPreCompleted; var buffer = new ArraySegment(new byte[bufferSize], 0, bufferSize); @@ -152,7 +149,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests } }; - using (var memory = new MemoryPool()) using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext())) { kestrelEngine.Start(count: 1); @@ -162,7 +158,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests var trace = new KestrelTrace(new TestKestrelTrace()); var ltp = new LoggingThreadPool(trace); var mockConnection = new MockConnection(); - var socketOutput = new SocketOutput(kestrelThread, socket, memory, mockConnection, "0", trace, ltp, new Queue()); + var socketOutput = new SocketOutput(kestrelThread, socket, mockConnection, "0", trace, ltp); var bufferSize = maxBytesPreCompleted / 2; var data = new byte[bufferSize]; @@ -231,7 +227,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests } }; - using (var memory = new MemoryPool()) using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext())) { kestrelEngine.Start(count: 1); @@ -240,10 +235,10 @@ namespace Microsoft.AspNetCore.Server.KestrelTests var socket = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace()); var trace = new KestrelTrace(new TestKestrelTrace()); var ltp = new LoggingThreadPool(trace); - + using (var mockConnection = new MockConnection()) { - ISocketOutput socketOutput = new SocketOutput(kestrelThread, socket, memory, mockConnection, "0", trace, ltp, new Queue()); + ISocketOutput socketOutput = new SocketOutput(kestrelThread, socket, mockConnection, "0", trace, ltp); var bufferSize = maxBytesPreCompleted; @@ -348,7 +343,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests } }; - using (var memory = new MemoryPool()) using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext())) { kestrelEngine.Start(count: 1); @@ -361,7 +355,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests using (var mockConnection = new MockConnection()) { var abortedSource = mockConnection.RequestAbortedSource; - ISocketOutput socketOutput = new SocketOutput(kestrelThread, socket, memory, mockConnection, "0", trace, ltp, new Queue()); + ISocketOutput socketOutput = new SocketOutput(kestrelThread, socket, mockConnection, "0", trace, ltp); var bufferSize = maxBytesPreCompleted; @@ -441,7 +435,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests } }; - using (var memory = new MemoryPool()) using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext())) { kestrelEngine.Start(count: 1); @@ -451,7 +444,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests var trace = new KestrelTrace(new TestKestrelTrace()); var ltp = new LoggingThreadPool(trace); var mockConnection = new MockConnection(); - var socketOutput = new SocketOutput(kestrelThread, socket, memory, mockConnection, "0", trace, ltp, new Queue()); + var socketOutput = new SocketOutput(kestrelThread, socket, mockConnection, "0", trace, ltp); var bufferSize = maxBytesPreCompleted; var buffer = new ArraySegment(new byte[bufferSize], 0, bufferSize); @@ -534,7 +527,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests } }; - using (var memory = new MemoryPool()) using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext())) { kestrelEngine.Start(count: 1); @@ -543,14 +535,14 @@ namespace Microsoft.AspNetCore.Server.KestrelTests var socket = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace()); var trace = new KestrelTrace(new TestKestrelTrace()); var ltp = new LoggingThreadPool(trace); - var socketOutput = new SocketOutput(kestrelThread, socket, memory, new MockConnection(), "0", trace, ltp, new Queue()); + var socketOutput = new SocketOutput(kestrelThread, socket, new MockConnection(), "0", trace, ltp); // block 1 var start = socketOutput.ProducingStart(); start.Block.End = start.Block.Data.Offset + start.Block.Data.Count; // block 2 - var block2 = memory.Lease(); + var block2 = kestrelThread.Memory.Lease(); block2.End = block2.Data.Offset + block2.Data.Count; start.Block.Next = block2; @@ -586,7 +578,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests } }; - using (var memory = new MemoryPool()) using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext())) { kestrelEngine.Start(count: 1); @@ -596,7 +587,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests var trace = new KestrelTrace(new TestKestrelTrace()); var ltp = new LoggingThreadPool(trace); var mockConnection = new MockConnection(); - var socketOutput = new SocketOutput(kestrelThread, socket, memory, mockConnection, "0", trace, ltp, new Queue()); + var socketOutput = new SocketOutput(kestrelThread, socket, mockConnection, "0", trace, ltp); var buffer = new ArraySegment(new byte[1]); @@ -656,7 +647,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests } }; - using (var memory = new MemoryPool()) using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext())) { kestrelEngine.Start(count: 1); @@ -665,7 +655,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests var socket = new MockSocket(mockLibuv, kestrelThread.Loop.ThreadId, new TestKestrelTrace()); var trace = new KestrelTrace(new TestKestrelTrace()); var ltp = new LoggingThreadPool(trace); - var socketOutput = new SocketOutput(kestrelThread, socket, memory, new MockConnection(), "0", trace, ltp, new Queue()); + var socketOutput = new SocketOutput(kestrelThread, socket, new MockConnection(), "0", trace, ltp); var blockThreadWh = new ManualResetEventSlim(); kestrelThread.Post(_ => @@ -702,7 +692,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests { var mockLibuv = new MockLibuv(); - using (var memory = new MemoryPool()) using (var kestrelEngine = new KestrelEngine(mockLibuv, new TestServiceContext())) { kestrelEngine.Start(count: 1); @@ -712,7 +701,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests var trace = new KestrelTrace(new TestKestrelTrace()); var ltp = new LoggingThreadPool(trace); var connection = new MockConnection(); - var socketOutput = new SocketOutput(kestrelThread, socket, memory, connection, "0", trace, ltp, new Queue()); + var socketOutput = new SocketOutput(kestrelThread, socket, connection, "0", trace, ltp); // Close SocketOutput var cleanupTask = socketOutput.WriteAsync(