diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs index 87658395f2..de603b4458 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/KestrelThread.cs @@ -18,6 +18,11 @@ namespace Microsoft.AspNet.Server.Kestrel /// public class KestrelThread { + // maximum times the work queues swapped and are processed in a single pass + // as completing a task may immediately have write data to put on the network + // otherwise it needs to wait till the next pass of the libuv loop + private const int _maxLoops = 8; + private static Action _threadCallbackAdapter = (callback, state) => ((Action)callback).Invoke((KestrelThread)state); private KestrelEngine _engine; private readonly IApplicationLifetime _appLifetime; @@ -249,11 +254,17 @@ namespace Microsoft.AspNet.Server.Kestrel private void OnPost() { - DoPostWork(); - DoPostCloseHandle(); + var loopsRemaining = _maxLoops; + bool wasWork; + do + { + wasWork = DoPostWork(); + wasWork = DoPostCloseHandle() || wasWork; + loopsRemaining--; + } while (wasWork && loopsRemaining > 0); } - private void DoPostWork() + private bool DoPostWork() { Queue queue; lock (_workSync) @@ -262,6 +273,9 @@ namespace Microsoft.AspNet.Server.Kestrel _workAdding = _workRunning; _workRunning = queue; } + + bool wasWork = queue.Count > 0; + while (queue.Count != 0) { var work = queue.Dequeue(); @@ -286,8 +300,10 @@ namespace Microsoft.AspNet.Server.Kestrel } } } + + return wasWork; } - private void DoPostCloseHandle() + private bool DoPostCloseHandle() { Queue queue; lock (_workSync) @@ -296,6 +312,9 @@ namespace Microsoft.AspNet.Server.Kestrel _closeHandleAdding = _closeHandleRunning; _closeHandleRunning = queue; } + + bool wasWork = queue.Count > 0; + while (queue.Count != 0) { var closeHandle = queue.Dequeue(); @@ -309,6 +328,8 @@ namespace Microsoft.AspNet.Server.Kestrel throw; } } + + return wasWork; } private struct Work