Replace ManualResetEvents with a TCS (#6173)
* Added TaskCreationOptions.RunContinuationsAsynchronously in a few places
This commit is contained in:
parent
dd912850eb
commit
b12c33dbc3
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -21,6 +21,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
public void OnConnectionCreatesLogScopeWithConnectionId()
|
public void OnConnectionCreatesLogScopeWithConnectionId()
|
||||||
{
|
{
|
||||||
var serviceContext = new TestServiceContext();
|
var serviceContext = new TestServiceContext();
|
||||||
|
// This needs to run inline
|
||||||
var tcs = new TaskCompletionSource<object>();
|
var tcs = new TaskCompletionSource<object>();
|
||||||
var dispatcher = new ConnectionDispatcher(serviceContext, _ => tcs.Task);
|
var dispatcher = new ConnectionDispatcher(serviceContext, _ => tcs.Task);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -473,23 +473,26 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task DATA_Received_Multiplexed_AppMustNotBlockOtherFrames()
|
public async Task DATA_Received_Multiplexed_AppMustNotBlockOtherFrames()
|
||||||
{
|
{
|
||||||
var stream1Read = new ManualResetEvent(false);
|
var stream1Read = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
var stream1ReadFinished = new ManualResetEvent(false);
|
var stream1ReadFinished = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
var stream3Read = new ManualResetEvent(false);
|
var stream3Read = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
var stream3ReadFinished = new ManualResetEvent(false);
|
var stream3ReadFinished = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
|
|
||||||
await InitializeConnectionAsync(async context =>
|
await InitializeConnectionAsync(async context =>
|
||||||
{
|
{
|
||||||
var data = new byte[10];
|
var data = new byte[10];
|
||||||
var read = await context.Request.Body.ReadAsync(new byte[10], 0, 10);
|
var read = await context.Request.Body.ReadAsync(new byte[10], 0, 10);
|
||||||
if (context.Features.Get<IHttp2StreamIdFeature>().StreamId == 1)
|
if (context.Features.Get<IHttp2StreamIdFeature>().StreamId == 1)
|
||||||
{
|
{
|
||||||
stream1Read.Set();
|
stream1Read.TrySetResult(null);
|
||||||
Assert.True(stream1ReadFinished.WaitOne(TimeSpan.FromSeconds(10)));
|
|
||||||
|
await stream1ReadFinished.Task.DefaultTimeout();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stream3Read.Set();
|
stream3Read.TrySetResult(null);
|
||||||
Assert.True(stream3ReadFinished.WaitOne(TimeSpan.FromSeconds(10)));
|
|
||||||
|
await stream3ReadFinished.Task.DefaultTimeout();
|
||||||
}
|
}
|
||||||
await context.Response.Body.WriteAsync(data, 0, read);
|
await context.Response.Body.WriteAsync(data, 0, read);
|
||||||
});
|
});
|
||||||
|
|
@ -498,12 +501,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
await StartStreamAsync(3, _browserRequestHeaders, endStream: false);
|
await StartStreamAsync(3, _browserRequestHeaders, endStream: false);
|
||||||
|
|
||||||
await SendDataAsync(1, _helloBytes, endStream: true);
|
await SendDataAsync(1, _helloBytes, endStream: true);
|
||||||
Assert.True(stream1Read.WaitOne(TimeSpan.FromSeconds(10)));
|
await stream1Read.Task.DefaultTimeout();
|
||||||
|
|
||||||
await SendDataAsync(3, _helloBytes, endStream: true);
|
await SendDataAsync(3, _helloBytes, endStream: true);
|
||||||
Assert.True(stream3Read.WaitOne(TimeSpan.FromSeconds(10)));
|
await stream3Read.Task.DefaultTimeout();
|
||||||
|
|
||||||
stream3ReadFinished.Set();
|
stream3ReadFinished.TrySetResult(null);
|
||||||
|
|
||||||
await ExpectAsync(Http2FrameType.HEADERS,
|
await ExpectAsync(Http2FrameType.HEADERS,
|
||||||
withLength: 37,
|
withLength: 37,
|
||||||
|
|
@ -518,7 +521,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
withFlags: (byte)Http2DataFrameFlags.END_STREAM,
|
withFlags: (byte)Http2DataFrameFlags.END_STREAM,
|
||||||
withStreamId: 3);
|
withStreamId: 3);
|
||||||
|
|
||||||
stream1ReadFinished.Set();
|
stream1ReadFinished.TrySetResult(null);
|
||||||
|
|
||||||
await ExpectAsync(Http2FrameType.HEADERS,
|
await ExpectAsync(Http2FrameType.HEADERS,
|
||||||
withLength: 37,
|
withLength: 37,
|
||||||
|
|
@ -1197,33 +1200,36 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task HEADERS_Received_AppCannotBlockOtherFrames()
|
public async Task HEADERS_Received_AppCannotBlockOtherFrames()
|
||||||
{
|
{
|
||||||
var firstRequestReceived = new ManualResetEvent(false);
|
var firstRequestReceived = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
var finishFirstRequest = new ManualResetEvent(false);
|
var finishFirstRequest = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
var secondRequestReceived = new ManualResetEvent(false);
|
var secondRequestReceived = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
var finishSecondRequest = new ManualResetEvent(false);
|
var finishSecondRequest = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
await InitializeConnectionAsync(context =>
|
|
||||||
|
await InitializeConnectionAsync(async context =>
|
||||||
{
|
{
|
||||||
if (!firstRequestReceived.WaitOne(0))
|
if (!firstRequestReceived.Task.IsCompleted)
|
||||||
{
|
{
|
||||||
firstRequestReceived.Set();
|
firstRequestReceived.TrySetResult(null);
|
||||||
Assert.True(finishFirstRequest.WaitOne(TimeSpan.FromSeconds(10)));
|
|
||||||
|
await finishFirstRequest.Task.DefaultTimeout();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
secondRequestReceived.Set();
|
secondRequestReceived.TrySetResult(null);
|
||||||
Assert.True(finishSecondRequest.WaitOne(TimeSpan.FromSeconds(10)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
await finishSecondRequest.Task.DefaultTimeout();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await StartStreamAsync(1, _browserRequestHeaders, endStream: true);
|
await StartStreamAsync(1, _browserRequestHeaders, endStream: true);
|
||||||
Assert.True(firstRequestReceived.WaitOne(TimeSpan.FromSeconds(10)));
|
|
||||||
|
await firstRequestReceived.Task.DefaultTimeout();
|
||||||
|
|
||||||
await StartStreamAsync(3, _browserRequestHeaders, endStream: true);
|
await StartStreamAsync(3, _browserRequestHeaders, endStream: true);
|
||||||
Assert.True(secondRequestReceived.WaitOne(TimeSpan.FromSeconds(10)));
|
|
||||||
|
|
||||||
finishSecondRequest.Set();
|
await secondRequestReceived.Task.DefaultTimeout();
|
||||||
|
|
||||||
|
finishSecondRequest.TrySetResult(null);
|
||||||
|
|
||||||
await ExpectAsync(Http2FrameType.HEADERS,
|
await ExpectAsync(Http2FrameType.HEADERS,
|
||||||
withLength: 55,
|
withLength: 55,
|
||||||
|
|
@ -1234,7 +1240,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
withFlags: (byte)Http2DataFrameFlags.END_STREAM,
|
withFlags: (byte)Http2DataFrameFlags.END_STREAM,
|
||||||
withStreamId: 3);
|
withStreamId: 3);
|
||||||
|
|
||||||
finishFirstRequest.Set();
|
finishFirstRequest.TrySetResult(null);
|
||||||
|
|
||||||
await ExpectAsync(Http2FrameType.HEADERS,
|
await ExpectAsync(Http2FrameType.HEADERS,
|
||||||
withLength: 55,
|
withLength: 55,
|
||||||
|
|
@ -1255,7 +1261,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
|
|
||||||
_connection.ServerSettings.MaxConcurrentStreams = 1;
|
_connection.ServerSettings.MaxConcurrentStreams = 1;
|
||||||
|
|
||||||
var requestBlocker = new TaskCompletionSource<object>();
|
var requestBlocker = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
await InitializeConnectionAsync(context => requestBlocker.Task);
|
await InitializeConnectionAsync(context => requestBlocker.Task);
|
||||||
|
|
||||||
await StartStreamAsync(1, _browserRequestHeaders, endStream: true);
|
await StartStreamAsync(1, _browserRequestHeaders, endStream: true);
|
||||||
|
|
@ -1665,7 +1671,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
{
|
{
|
||||||
// > MaxRequestHeaderCount (100)
|
// > MaxRequestHeaderCount (100)
|
||||||
var headers = new List<KeyValuePair<string, string>>();
|
var headers = new List<KeyValuePair<string, string>>();
|
||||||
headers.AddRange(new []
|
headers.AddRange(new[]
|
||||||
{
|
{
|
||||||
new KeyValuePair<string, string>(HeaderNames.Method, "GET"),
|
new KeyValuePair<string, string>(HeaderNames.Method, "GET"),
|
||||||
new KeyValuePair<string, string>(HeaderNames.Path, "/"),
|
new KeyValuePair<string, string>(HeaderNames.Path, "/"),
|
||||||
|
|
@ -3863,7 +3869,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
await SendDataAsync(1, new byte[100], endStream: true);
|
await SendDataAsync(1, new byte[100], endStream: true);
|
||||||
// An extra one to break it
|
// An extra one to break it
|
||||||
await SendDataAsync(1, new byte[100], endStream: true);
|
await SendDataAsync(1, new byte[100], endStream: true);
|
||||||
|
|
||||||
// There's a race where either of these messages could be logged, depending on if the stream cleanup has finished yet.
|
// There's a race where either of these messages could be logged, depending on if the stream cleanup has finished yet.
|
||||||
await WaitForConnectionErrorAsync<Http2ConnectionErrorException>(
|
await WaitForConnectionErrorAsync<Http2ConnectionErrorException>(
|
||||||
ignoreNonGoAwayFrames: false,
|
ignoreNonGoAwayFrames: false,
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ namespace System.Buffers
|
||||||
_rentTracking = rentTracking;
|
_rentTracking = rentTracking;
|
||||||
_blocks = new HashSet<DiagnosticPoolBlock>();
|
_blocks = new HashSet<DiagnosticPoolBlock>();
|
||||||
_syncObj = new object();
|
_syncObj = new object();
|
||||||
_allBlocksReturned = new TaskCompletionSource<object>();
|
_allBlocksReturned = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
_blockAccessExceptions = new List<Exception>();
|
_blockAccessExceptions = new List<Exception>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue