Don't invoke continuations inline in OnCompleted (#12261)

This commit is contained in:
Stephen Halter 2019-07-16 22:14:16 -07:00 committed by GitHub
parent 4ba66f05bf
commit fb12909417
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 6 additions and 8 deletions

View File

@ -5,6 +5,7 @@ using System;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl 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) || if (ReferenceEquals(_callback, _callbackCompleted) ||
ReferenceEquals(Interlocked.CompareExchange(ref _callback, continuation, null), _callbackCompleted)) ReferenceEquals(Interlocked.CompareExchange(ref _callback, continuation, null), _callbackCompleted))
{ {
continuation(); Task.Run(continuation);
} }
} }

View File

@ -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 // There should never be a race between IsCompleted and OnCompleted since both operations
// should always be on the libuv thread // should always be on the libuv thread
if (ReferenceEquals(_callback, _callbackCompleted))
if (ReferenceEquals(_callback, _callbackCompleted) ||
ReferenceEquals(Interlocked.CompareExchange(ref _callback, continuation, null), _callbackCompleted))
{ {
Debug.Fail($"{typeof(LibuvAwaitable<TRequest>)}.{nameof(OnCompleted)} raced with {nameof(IsCompleted)}, running callback inline."); Debug.Fail($"{typeof(LibuvAwaitable<TRequest>)}.{nameof(OnCompleted)} raced with {nameof(IsCompleted)}, scheduling callback.");
// Just run it inline
continuation();
} }
_callback = continuation;
} }
public void UnsafeOnCompleted(Action continuation) public void UnsafeOnCompleted(Action continuation)