From c082af307d252a7ad755c729f1de55b6cfb25c5a Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Tue, 3 Aug 2021 22:06:00 -0700 Subject: [PATCH] make Quic AcceptStreamAsync concurrent safe (#56768) * make AcceptStreamAsync concurrent safe * feedback from review --- .../Implementations/MsQuic/MsQuicConnection.cs | 1 - .../tests/FunctionalTests/QuicStreamTests.cs | 29 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs index 82638fc..b3cbb93 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs @@ -74,7 +74,6 @@ namespace System.Net.Quic.Implementations.MsQuic // Backlog limit is managed by MsQuic so it can be unbounded here. public readonly Channel AcceptQueue = Channel.CreateUnbounded(new UnboundedChannelOptions() { - SingleReader = true, SingleWriter = true, }); diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamTests.cs index d350c86..438f836 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamTests.cs @@ -160,6 +160,35 @@ namespace System.Net.Quic.Tests } [Fact] + public async Task MultipleConcurrentStreamsOnSingleConnection() + { + const int count = 100; + Task[] tasks = new Task[count]; + + (QuicConnection clientConnection, QuicConnection serverConnection) = await CreateConnectedQuicConnection(); + using (clientConnection) + using (serverConnection) + { + for (int i = 0; i < count; i++) + { + tasks[i] = MakeStreams(clientConnection, serverConnection); + } + await tasks.WhenAllOrAnyFailed(PassingTestTimeoutMilliseconds); + } + + static async Task MakeStreams(QuicConnection clientConnection, QuicConnection serverConnection) + { + byte[] buffer = new byte[64]; + QuicStream clientStream = clientConnection.OpenBidirectionalStream(); + ValueTask writeTask = clientStream.WriteAsync(Encoding.UTF8.GetBytes("PING"), endStream: true); + ValueTask acceptTask = serverConnection.AcceptStreamAsync(); + await new Task[] { writeTask.AsTask(), acceptTask.AsTask()}.WhenAllOrAnyFailed(PassingTestTimeoutMilliseconds); + QuicStream serverStream = acceptTask.Result; + await serverStream.ReadAsync(buffer); + } + } + + [Fact] public async Task GetStreamIdWithoutStartWorks() { using QuicListener listener = CreateQuicListener(); -- 2.7.4