diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs index 5c5d204564..d963d6f022 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs @@ -287,7 +287,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core var connectionHandler = new ConnectionHandler(ipv4ListenOptions, serviceContext, application); var transport = _transportFactory.Create(ipv4ListenOptions, connectionHandler); _transports.Add(transport); - await transport.BindAsync(); + await transport.BindAsync().ConfigureAwait(false); } catch (AddressInUseException ex) { @@ -306,7 +306,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core var connectionHandler = new ConnectionHandler(ipv6ListenOptions, serviceContext, application); var transport = _transportFactory.Create(ipv6ListenOptions, connectionHandler); _transports.Add(transport); - await transport.BindAsync(); + await transport.BindAsync().ConfigureAwait(false); } catch (AddressInUseException ex) { diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvConnection.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvConnection.cs index 0e997c7b51..483a4fd050 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvConnection.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvConnection.cs @@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal private readonly UvStreamHandle _socket; private IConnectionContext _connectionContext; - private TaskCompletionSource _socketClosedTcs = new TaskCompletionSource(); + private TaskCompletionSource _socketClosedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); private WritableBuffer? _currentWritableBuffer; diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvConnectionManager.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvConnectionManager.cs index 14f314510d..9cc99b919a 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvConnectionManager.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvConnectionManager.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal private async Task WalkConnectionsAsync(Action> action, TimeSpan timeout) { - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); _thread.Post(state => action(state, tcs), this); diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvThread.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvThread.cs index 5fb6f33d00..d183f20f72 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvThread.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/LibuvThread.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal private readonly LibuvTransport _transport; private readonly IApplicationLifetime _appLifetime; private readonly Thread _thread; - private readonly TaskCompletionSource _threadTcs = new TaskCompletionSource(); + private readonly TaskCompletionSource _threadTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); private readonly UvLoopHandle _loop; private readonly UvAsyncHandle _post; private Queue _workAdding = new Queue(1024); @@ -87,7 +87,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal public Task StartAsync() { - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); _thread.Start(tcs); return tcs.Task; } @@ -203,7 +203,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal public Task PostAsync(Action callback, T state) { - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); lock (_workSync) { _workAdding.Enqueue(new Work @@ -332,36 +332,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal try { work.CallbackAdapter(work.Callback, work.State); - if (work.Completion != null) - { - ThreadPool.QueueUserWorkItem(o => - { - try - { - ((TaskCompletionSource)o).SetResult(null); - } - catch (Exception e) - { - _log.LogError(0, e, $"{nameof(LibuvThread)}.{nameof(DoPostWork)}"); - } - }, work.Completion); - } + work.Completion?.TrySetResult(null); } catch (Exception ex) { if (work.Completion != null) { - ThreadPool.QueueUserWorkItem(o => - { - try - { - ((TaskCompletionSource)o).TrySetException(ex); - } - catch (Exception e) - { - _log.LogError(0, e, $"{nameof(LibuvThread)}.{nameof(DoPostWork)}"); - } - }, work.Completion); + work.Completion.TrySetException(ex); } else { diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/Listener.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/Listener.cs index aa03493751..d9d1cf1798 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/Listener.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/Listener.cs @@ -31,25 +31,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal EndPointInformation = endPointInformation; Thread = thread; - var tcs = new TaskCompletionSource(this); - - Thread.Post(state => + return Thread.PostAsync(listener => { - var tcs2 = state; - try - { - var listener = ((Listener) tcs2.Task.AsyncState); - listener.ListenSocket = listener.CreateListenSocket(); - ListenSocket.Listen(LibuvConstants.ListenBacklog, ConnectionCallback, this); - tcs2.SetResult(0); - } - catch (Exception ex) - { - tcs2.SetException(ex); - } - }, tcs); - - return tcs.Task; + listener.ListenSocket = listener.CreateListenSocket(); + listener.ListenSocket.Listen(LibuvConstants.ListenBacklog, ConnectionCallback, listener); + }, this); } /// @@ -157,9 +143,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal // the exception that stopped the event loop will never be surfaced. if (Thread.FatalError == null && ListenSocket != null) { - await Thread.PostAsync(state => + await Thread.PostAsync(listener => { - var listener = (Listener)state; listener.ListenSocket.Dispose(); listener._closed = true; diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerPrimary.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerPrimary.cs index 7ebe34b709..d1cdcd150f 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerPrimary.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerPrimary.cs @@ -53,8 +53,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal await StartAsync(endPointInformation, thread).ConfigureAwait(false); - await Thread.PostAsync(state => ((ListenerPrimary)state).PostCallback(), - this).ConfigureAwait(false); + await Thread.PostAsync(listener => listener.PostCallback(), this).ConfigureAwait(false); } private void PostCallback() @@ -175,9 +174,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal if (Thread.FatalError == null && ListenPipe != null) { - await Thread.PostAsync(state => + await Thread.PostAsync(listener => { - var listener = (ListenerPrimary)state; listener.ListenPipe.Dispose(); foreach (var dispatchPipe in listener._dispatchPipes) diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerSecondary.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerSecondary.cs index 25c7d1ab6d..ced08d8126 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerSecondary.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerSecondary.cs @@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal Thread = thread; DispatchPipe = new UvPipeHandle(Log); - var tcs = new TaskCompletionSource(this); + var tcs = new TaskCompletionSource(this, TaskCreationOptions.RunContinuationsAsynchronously); Thread.Post(StartCallback, tcs); return tcs.Task; } @@ -185,9 +185,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal // the exception that stopped the event loop will never be surfaced. if (Thread.FatalError == null) { - await Thread.PostAsync(state => + await Thread.PostAsync(listener => { - var listener = (ListenerSecondary)state; listener.DispatchPipe.Dispose(); listener.FreeBuffer();