Skip to content

Commit b12c33d

Browse files
authored
Replace ManualResetEvents with a TCS (#6173)
* Added TaskCreationOptions.RunContinuationsAsynchronously in a few places
1 parent dd91285 commit b12c33d

File tree

3 files changed

+40
-33
lines changed

3 files changed

+40
-33
lines changed

src/Servers/Kestrel/Core/test/ConnectionDispatcherTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
@@ -21,6 +21,7 @@ public class ConnectionDispatcherTests
2121
public void OnConnectionCreatesLogScopeWithConnectionId()
2222
{
2323
var serviceContext = new TestServiceContext();
24+
// This needs to run inline
2425
var tcs = new TaskCompletionSource<object>();
2526
var dispatcher = new ConnectionDispatcher(serviceContext, _ => tcs.Task);
2627

src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -473,23 +473,26 @@ await ExpectAsync(Http2FrameType.DATA,
473473
[Fact]
474474
public async Task DATA_Received_Multiplexed_AppMustNotBlockOtherFrames()
475475
{
476-
var stream1Read = new ManualResetEvent(false);
477-
var stream1ReadFinished = new ManualResetEvent(false);
478-
var stream3Read = new ManualResetEvent(false);
479-
var stream3ReadFinished = new ManualResetEvent(false);
476+
var stream1Read = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
477+
var stream1ReadFinished = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
478+
var stream3Read = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
479+
var stream3ReadFinished = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
480+
480481
await InitializeConnectionAsync(async context =>
481482
{
482483
var data = new byte[10];
483484
var read = await context.Request.Body.ReadAsync(new byte[10], 0, 10);
484485
if (context.Features.Get<IHttp2StreamIdFeature>().StreamId == 1)
485486
{
486-
stream1Read.Set();
487-
Assert.True(stream1ReadFinished.WaitOne(TimeSpan.FromSeconds(10)));
487+
stream1Read.TrySetResult(null);
488+
489+
await stream1ReadFinished.Task.DefaultTimeout();
488490
}
489491
else
490492
{
491-
stream3Read.Set();
492-
Assert.True(stream3ReadFinished.WaitOne(TimeSpan.FromSeconds(10)));
493+
stream3Read.TrySetResult(null);
494+
495+
await stream3ReadFinished.Task.DefaultTimeout();
493496
}
494497
await context.Response.Body.WriteAsync(data, 0, read);
495498
});
@@ -498,12 +501,12 @@ await InitializeConnectionAsync(async context =>
498501
await StartStreamAsync(3, _browserRequestHeaders, endStream: false);
499502

500503
await SendDataAsync(1, _helloBytes, endStream: true);
501-
Assert.True(stream1Read.WaitOne(TimeSpan.FromSeconds(10)));
504+
await stream1Read.Task.DefaultTimeout();
502505

503506
await SendDataAsync(3, _helloBytes, endStream: true);
504-
Assert.True(stream3Read.WaitOne(TimeSpan.FromSeconds(10)));
507+
await stream3Read.Task.DefaultTimeout();
505508

506-
stream3ReadFinished.Set();
509+
stream3ReadFinished.TrySetResult(null);
507510

508511
await ExpectAsync(Http2FrameType.HEADERS,
509512
withLength: 37,
@@ -518,7 +521,7 @@ await ExpectAsync(Http2FrameType.DATA,
518521
withFlags: (byte)Http2DataFrameFlags.END_STREAM,
519522
withStreamId: 3);
520523

521-
stream1ReadFinished.Set();
524+
stream1ReadFinished.TrySetResult(null);
522525

523526
await ExpectAsync(Http2FrameType.HEADERS,
524527
withLength: 37,
@@ -1197,33 +1200,36 @@ await ExpectAsync(Http2FrameType.DATA,
11971200
[Fact]
11981201
public async Task HEADERS_Received_AppCannotBlockOtherFrames()
11991202
{
1200-
var firstRequestReceived = new ManualResetEvent(false);
1201-
var finishFirstRequest = new ManualResetEvent(false);
1202-
var secondRequestReceived = new ManualResetEvent(false);
1203-
var finishSecondRequest = new ManualResetEvent(false);
1204-
await InitializeConnectionAsync(context =>
1203+
var firstRequestReceived = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
1204+
var finishFirstRequest = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
1205+
var secondRequestReceived = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
1206+
var finishSecondRequest = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
1207+
1208+
await InitializeConnectionAsync(async context =>
12051209
{
1206-
if (!firstRequestReceived.WaitOne(0))
1210+
if (!firstRequestReceived.Task.IsCompleted)
12071211
{
1208-
firstRequestReceived.Set();
1209-
Assert.True(finishFirstRequest.WaitOne(TimeSpan.FromSeconds(10)));
1212+
firstRequestReceived.TrySetResult(null);
1213+
1214+
await finishFirstRequest.Task.DefaultTimeout();
12101215
}
12111216
else
12121217
{
1213-
secondRequestReceived.Set();
1214-
Assert.True(finishSecondRequest.WaitOne(TimeSpan.FromSeconds(10)));
1215-
}
1218+
secondRequestReceived.TrySetResult(null);
12161219

1217-
return Task.CompletedTask;
1220+
await finishSecondRequest.Task.DefaultTimeout();
1221+
}
12181222
});
12191223

12201224
await StartStreamAsync(1, _browserRequestHeaders, endStream: true);
1221-
Assert.True(firstRequestReceived.WaitOne(TimeSpan.FromSeconds(10)));
1225+
1226+
await firstRequestReceived.Task.DefaultTimeout();
12221227

12231228
await StartStreamAsync(3, _browserRequestHeaders, endStream: true);
1224-
Assert.True(secondRequestReceived.WaitOne(TimeSpan.FromSeconds(10)));
12251229

1226-
finishSecondRequest.Set();
1230+
await secondRequestReceived.Task.DefaultTimeout();
1231+
1232+
finishSecondRequest.TrySetResult(null);
12271233

12281234
await ExpectAsync(Http2FrameType.HEADERS,
12291235
withLength: 55,
@@ -1234,7 +1240,7 @@ await ExpectAsync(Http2FrameType.DATA,
12341240
withFlags: (byte)Http2DataFrameFlags.END_STREAM,
12351241
withStreamId: 3);
12361242

1237-
finishFirstRequest.Set();
1243+
finishFirstRequest.TrySetResult(null);
12381244

12391245
await ExpectAsync(Http2FrameType.HEADERS,
12401246
withLength: 55,
@@ -1255,7 +1261,7 @@ public async Task HEADERS_OverMaxStreamLimit_Refused()
12551261

12561262
_connection.ServerSettings.MaxConcurrentStreams = 1;
12571263

1258-
var requestBlocker = new TaskCompletionSource<object>();
1264+
var requestBlocker = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
12591265
await InitializeConnectionAsync(context => requestBlocker.Task);
12601266

12611267
await StartStreamAsync(1, _browserRequestHeaders, endStream: true);
@@ -1665,7 +1671,7 @@ public Task HEADERS_Received_TooManyHeaders_ConnectionError()
16651671
{
16661672
// > MaxRequestHeaderCount (100)
16671673
var headers = new List<KeyValuePair<string, string>>();
1668-
headers.AddRange(new []
1674+
headers.AddRange(new[]
16691675
{
16701676
new KeyValuePair<string, string>(HeaderNames.Method, "GET"),
16711677
new KeyValuePair<string, string>(HeaderNames.Path, "/"),
@@ -3863,7 +3869,7 @@ public async Task AbortedStream_ResetsAndDrainsRequest_RefusesFramesAfterEndOfSt
38633869
await SendDataAsync(1, new byte[100], endStream: true);
38643870
// An extra one to break it
38653871
await SendDataAsync(1, new byte[100], endStream: true);
3866-
3872+
38673873
// There's a race where either of these messages could be logged, depending on if the stream cleanup has finished yet.
38683874
await WaitForConnectionErrorAsync<Http2ConnectionErrorException>(
38693875
ignoreNonGoAwayFrames: false,

src/Shared/Buffers.MemoryPool/DiagnosticMemoryPool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public DiagnosticMemoryPool(MemoryPool<byte> pool, bool allowLateReturn = false,
4040
_rentTracking = rentTracking;
4141
_blocks = new HashSet<DiagnosticPoolBlock>();
4242
_syncObj = new object();
43-
_allBlocksReturned = new TaskCompletionSource<object>();
43+
_allBlocksReturned = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
4444
_blockAccessExceptions = new List<Exception>();
4545
}
4646

0 commit comments

Comments
 (0)