Process cascaded work immediately

Without waiting for next libuv pass

Fix for potential regression in #363 due to bug fix.
This commit is contained in:
Ben Adams 2015-11-25 04:44:07 +00:00
parent 97d3340624
commit 992664e0dc
1 changed files with 25 additions and 4 deletions

View File

@ -18,6 +18,11 @@ namespace Microsoft.AspNet.Server.Kestrel
/// </summary> /// </summary>
public class KestrelThread 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<object, object> _threadCallbackAdapter = (callback, state) => ((Action<KestrelThread>)callback).Invoke((KestrelThread)state); private static Action<object, object> _threadCallbackAdapter = (callback, state) => ((Action<KestrelThread>)callback).Invoke((KestrelThread)state);
private KestrelEngine _engine; private KestrelEngine _engine;
private readonly IApplicationLifetime _appLifetime; private readonly IApplicationLifetime _appLifetime;
@ -249,11 +254,17 @@ namespace Microsoft.AspNet.Server.Kestrel
private void OnPost() private void OnPost()
{ {
DoPostWork(); var loopsRemaining = _maxLoops;
DoPostCloseHandle(); bool wasWork;
do
{
wasWork = DoPostWork();
wasWork = DoPostCloseHandle() || wasWork;
loopsRemaining--;
} while (wasWork && loopsRemaining > 0);
} }
private void DoPostWork() private bool DoPostWork()
{ {
Queue<Work> queue; Queue<Work> queue;
lock (_workSync) lock (_workSync)
@ -262,6 +273,9 @@ namespace Microsoft.AspNet.Server.Kestrel
_workAdding = _workRunning; _workAdding = _workRunning;
_workRunning = queue; _workRunning = queue;
} }
bool wasWork = queue.Count > 0;
while (queue.Count != 0) while (queue.Count != 0)
{ {
var work = queue.Dequeue(); var work = queue.Dequeue();
@ -286,8 +300,10 @@ namespace Microsoft.AspNet.Server.Kestrel
} }
} }
} }
return wasWork;
} }
private void DoPostCloseHandle() private bool DoPostCloseHandle()
{ {
Queue<CloseHandle> queue; Queue<CloseHandle> queue;
lock (_workSync) lock (_workSync)
@ -296,6 +312,9 @@ namespace Microsoft.AspNet.Server.Kestrel
_closeHandleAdding = _closeHandleRunning; _closeHandleAdding = _closeHandleRunning;
_closeHandleRunning = queue; _closeHandleRunning = queue;
} }
bool wasWork = queue.Count > 0;
while (queue.Count != 0) while (queue.Count != 0)
{ {
var closeHandle = queue.Dequeue(); var closeHandle = queue.Dequeue();
@ -309,6 +328,8 @@ namespace Microsoft.AspNet.Server.Kestrel
throw; throw;
} }
} }
return wasWork;
} }
private struct Work private struct Work