From fb129094178d0077a0ea0d6f26c7458afc80433c Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Tue, 16 Jul 2019 22:14:16 -0700 Subject: [PATCH] Don't invoke continuations inline in OnCompleted (#12261) --- .../Http2/FlowControl/OutputFlowControlAwaitable.cs | 3 ++- .../Transport.Libuv/src/Internal/LibuvAwaitable.cs | 11 ++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/FlowControl/OutputFlowControlAwaitable.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/FlowControl/OutputFlowControlAwaitable.cs index e9e44ab3ba..c691a22ed7 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/FlowControl/OutputFlowControlAwaitable.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/FlowControl/OutputFlowControlAwaitable.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Threading; +using System.Threading.Tasks; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl { @@ -29,7 +30,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl if (ReferenceEquals(_callback, _callbackCompleted) || ReferenceEquals(Interlocked.CompareExchange(ref _callback, continuation, null), _callbackCompleted)) { - continuation(); + Task.Run(continuation); } } diff --git a/src/Servers/Kestrel/Transport.Libuv/src/Internal/LibuvAwaitable.cs b/src/Servers/Kestrel/Transport.Libuv/src/Internal/LibuvAwaitable.cs index 8435a6cb32..7d8f85cdb0 100644 --- a/src/Servers/Kestrel/Transport.Libuv/src/Internal/LibuvAwaitable.cs +++ b/src/Servers/Kestrel/Transport.Libuv/src/Internal/LibuvAwaitable.cs @@ -53,15 +53,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal { // There should never be a race between IsCompleted and OnCompleted since both operations // should always be on the libuv thread - - if (ReferenceEquals(_callback, _callbackCompleted) || - ReferenceEquals(Interlocked.CompareExchange(ref _callback, continuation, null), _callbackCompleted)) + if (ReferenceEquals(_callback, _callbackCompleted)) { - Debug.Fail($"{typeof(LibuvAwaitable)}.{nameof(OnCompleted)} raced with {nameof(IsCompleted)}, running callback inline."); - - // Just run it inline - continuation(); + Debug.Fail($"{typeof(LibuvAwaitable)}.{nameof(OnCompleted)} raced with {nameof(IsCompleted)}, scheduling callback."); } + + _callback = continuation; } public void UnsafeOnCompleted(Action continuation)