Gracefully shutdown even when there are open connections

This commit is contained in:
Stephen Halter 2015-06-11 16:56:33 -07:00
parent 2bc5d9518b
commit b43e5940e5
4 changed files with 30 additions and 13 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@ _ReSharper.*/
packages/
artifacts/
PublishProfiles/
.vs/
*.user
*.suo
*.cache

View File

@ -53,12 +53,16 @@ namespace Microsoft.AspNet.Server.Kestrel
Post(OnStop, null);
if (!_thread.Join((int)timeout.TotalMilliseconds))
{
Post(OnStopImmediate, null);
Post(OnStopRude, null);
if (!_thread.Join((int)timeout.TotalMilliseconds))
{
Post(OnStopImmediate, null);
if (!_thread.Join((int)timeout.TotalMilliseconds))
{
#if DNX451
_thread.Abort();
_thread.Abort();
#endif
}
}
}
if (_closeError != null)
@ -72,6 +76,21 @@ namespace Microsoft.AspNet.Server.Kestrel
_post.Unreference();
}
private void OnStopRude(object obj)
{
_engine.Libuv.walk(
_loop,
(ptr, arg) =>
{
var handle = UvMemory.FromIntPtr<UvHandle>(ptr);
if (handle != _post)
{
handle.Dispose();
}
},
IntPtr.Zero);
}
private void OnStopImmediate(object obj)
{
_stopImmediate = true;
@ -133,14 +152,8 @@ namespace Microsoft.AspNet.Server.Kestrel
// run the loop one more time to delete the open handles
_post.Reference();
_post.DangerousClose();
_engine.Libuv.walk(
_loop,
(ptr, arg) =>
{
var handle = UvMemory.FromIntPtr<UvHandle>(ptr);
handle.Dispose();
},
IntPtr.Zero);
// Ensure the "DangerousClose" operation completes in the event loop.
var ran2 = _loop.Run();
_loop.Dispose();
@ -203,7 +216,7 @@ namespace Microsoft.AspNet.Server.Kestrel
queue = _closeHandleAdding;
_closeHandleAdding = _closeHandleRunning;
_closeHandleRunning = queue;
}
}
while (queue.Count != 0)
{
var closeHandle = queue.Dequeue();

View File

@ -32,9 +32,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
{
_uv.close(memory, _destroyMemory);
}
else
else if (_queueCloseHandle != null)
{
_queueCloseHandle(memory2 => _uv.close(memory2, _destroyMemory), memory);
// This can be called from the finalizer.
// Ensure the closure doesn't reference "this".
var uv = _uv;
_queueCloseHandle(memory2 => uv.close(memory2, _destroyMemory), memory);
}
}
return true;