diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/SocketOutput.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/SocketOutput.cs index d0d218ac5..6ba533802 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/SocketOutput.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/SocketOutput.cs @@ -135,7 +135,15 @@ public void End(ProduceEndType endType) private void ScheduleWrite() { - _thread.Post(_this => _this.WriteAllPending(), this); + // Don't post write to closed socket + if (!_socket.IsClosed) + { + _thread.Post(_this => _this.WriteAllPending(), this); + } + else + { + CompleteAllCallbacksWithError(_lastWriteError ?? new InvalidOperationException("Socket is closed")); + } } // This is called on the libuv event loop @@ -173,6 +181,20 @@ private void WriteAllPending() throw; } } + + private void CompleteAllCallbacksWithError(Exception error) + { + lock (_lockObj) + { + while (_callbacksPending.Count > 0) + { + var callbackContext = _callbacksPending.Dequeue(); + + // callback(error, state, calledInline) + callbackContext.Callback(error, callbackContext.State, false); + } + } + } // This is called on the libuv event loop private void OnWriteCompleted(Queue> writtenBuffers, int status, Exception error) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs index ef6fb7443..fa56f31d6 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Diagnostics; using System.Runtime.InteropServices; namespace Microsoft.AspNet.Server.Kestrel.Networking @@ -199,6 +200,9 @@ public void async_init(UvLoopHandle loop, UvAsyncHandle handle, uv_async_cb cb) protected Func _uv_async_send; public void async_send(UvAsyncHandle handle) { + // Can't Assert with .Validate as that checks threadId + // and this function is to post to correct thread. + Debug.Assert(!handle.IsInvalid, "Handle is invalid"); Check(_uv_async_send(handle)); }