From 94f5e59b97d26d46714874f3b836ae3560f96c1b Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 11 Feb 2020 14:36:26 -0800 Subject: [PATCH 1/8] Call start earlier --- .../Implementations/MsQuic/MsQuicStream.cs | 22 ++++++++++++------- .../tests/FunctionalTests/MsQuicTests.cs | 13 +++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs index 84ccd7d519e885..e3a4098119fc97 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -68,6 +68,8 @@ internal sealed class MsQuicStream : QuicStreamProvider // TODO consider using Interlocked.Exchange instead of a sync if we can avoid it. private object _sync = new object(); + private Task _startTask; + // Creates a new MsQuicStream internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, IntPtr nativeObjPtr, bool inbound) { @@ -93,6 +95,8 @@ internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, _shutdownWriteResettableCompletionSource = new ResettableCompletionSource(); SetCallbackHandler(); + + _startTask = StartWritesAsync(); } internal override bool CanRead => _canRead; @@ -178,14 +182,20 @@ private async ValueTask HandleWriteStartState(Can { throw new InvalidOperationException("Writing is not allowed on stream."); } - + bool shouldAwaitStart = false; lock (_sync) { if (_sendState == SendState.Aborted) { throw new OperationCanceledException("Sending has already been aborted on the stream"); } + + if (_started != StartState.Finished) + { + shouldAwaitStart = true; + } } + CancellationTokenRegistration registration = cancellationToken.Register(() => { bool shouldComplete = false; @@ -204,13 +214,10 @@ private async ValueTask HandleWriteStartState(Can } }); - // Implicit start on first write. - if (_started == StartState.None) + // Make sure start has completed + if (shouldAwaitStart) { - _started = StartState.Started; - - // TODO can optimize this by not having this method be async. - await StartWritesAsync(); + await _startTask; } return registration; @@ -1021,7 +1028,6 @@ private void ThrowIfDisposed() private enum StartState { None, - Started, Finished } diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 46afefaea2a6af..1f2dc38a31ab8d 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -321,6 +321,19 @@ public async Task CallDifferentWriteMethodsWorks() Assert.Equal(24, res); } + [Fact] + public async Task GetStreamIdWithoutStartWorks() + { + using QuicConnection clientConnection = CreateQuicConnection(DefaultListener.ListenEndPoint); + + ValueTask clientTask = clientConnection.ConnectAsync(); + using QuicConnection serverConnection = await DefaultListener.AcceptConnectionAsync(); + await clientTask; + + using QuicStream clientStream = clientConnection.OpenBidirectionalStream(); + Assert.Equals(0, clientStream.StreamId); + } + private static async Task CreateAndTestBidirectionalStream(QuicConnection c1, QuicConnection c2) { using (QuicStream s1 = c1.OpenBidirectionalStream()) From 7b535707ed8331e97a14ea01939bc057b1bb15e1 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 11 Feb 2020 18:58:21 -0800 Subject: [PATCH 2/8] tests --- .../System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs | 6 +++--- .../System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs index e3a4098119fc97..1a4b5a5fbc9b7d 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -5,7 +5,6 @@ using System.Buffers; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using System.Net.Quic.Implementations.MsQuic.Internal; using System.Runtime.InteropServices; using System.Threading; @@ -68,7 +67,7 @@ internal sealed class MsQuicStream : QuicStreamProvider // TODO consider using Interlocked.Exchange instead of a sync if we can avoid it. private object _sync = new object(); - private Task _startTask; + private ValueTask _startTask; // Creates a new MsQuicStream internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, IntPtr nativeObjPtr, bool inbound) @@ -182,6 +181,7 @@ private async ValueTask HandleWriteStartState(Can { throw new InvalidOperationException("Writing is not allowed on stream."); } + bool shouldAwaitStart = false; lock (_sync) { @@ -217,7 +217,7 @@ private async ValueTask HandleWriteStartState(Can // Make sure start has completed if (shouldAwaitStart) { - await _startTask; + await _startTask.ConfigureAwait(false); } return registration; diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 1f2dc38a31ab8d..8a46f42c0cdaac 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -324,14 +324,15 @@ public async Task CallDifferentWriteMethodsWorks() [Fact] public async Task GetStreamIdWithoutStartWorks() { - using QuicConnection clientConnection = CreateQuicConnection(DefaultListener.ListenEndPoint); + using QuicListener listener = CreateQuicListener(); + using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint); ValueTask clientTask = clientConnection.ConnectAsync(); - using QuicConnection serverConnection = await DefaultListener.AcceptConnectionAsync(); + using QuicConnection serverConnection = await listener.AcceptConnectionAsync(); await clientTask; using QuicStream clientStream = clientConnection.OpenBidirectionalStream(); - Assert.Equals(0, clientStream.StreamId); + Assert.Equal(0, clientStream.StreamId); } private static async Task CreateAndTestBidirectionalStream(QuicConnection c1, QuicConnection c2) From 4a56d1bc38677c56a60dd0e05be23f42c5ce08ec Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 11 Feb 2020 21:05:05 -0800 Subject: [PATCH 3/8] I really don't know what is going on --- .../Implementations/MsQuic/MsQuicStream.cs | 39 +++++++------------ .../tests/FunctionalTests/MsQuicTests.cs | 2 +- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs index 1a4b5a5fbc9b7d..be2d8d57abbbdf 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -44,7 +44,7 @@ internal sealed class MsQuicStream : QuicStreamProvider private GCHandle _sendHandle; // Used to check if StartAsync has been called. - private StartState _started; + private bool _started; private ReadState _readState; private long _readErrorCode = -1; @@ -67,7 +67,8 @@ internal sealed class MsQuicStream : QuicStreamProvider // TODO consider using Interlocked.Exchange instead of a sync if we can avoid it. private object _sync = new object(); - private ValueTask _startTask; + + private TaskCompletionSource _startTcs = new TaskCompletionSource(); // Creates a new MsQuicStream internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, IntPtr nativeObjPtr, bool inbound) @@ -78,13 +79,12 @@ internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, if (inbound) { - _started = StartState.Finished; + _started = true; _canWrite = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); _canRead = true; } else { - _started = StartState.None; _canWrite = true; _canRead = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); } @@ -92,10 +92,9 @@ internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, _sendResettableCompletionSource = new ResettableCompletionSource(); _receiveResettableCompletionSource = new ResettableCompletionSource(); _shutdownWriteResettableCompletionSource = new ResettableCompletionSource(); - SetCallbackHandler(); - _startTask = StartWritesAsync(); + StartWritesAsync(); } internal override bool CanRead => _canRead; @@ -182,18 +181,12 @@ private async ValueTask HandleWriteStartState(Can throw new InvalidOperationException("Writing is not allowed on stream."); } - bool shouldAwaitStart = false; lock (_sync) { if (_sendState == SendState.Aborted) { throw new OperationCanceledException("Sending has already been aborted on the stream"); } - - if (_started != StartState.Finished) - { - shouldAwaitStart = true; - } } CancellationTokenRegistration registration = cancellationToken.Register(() => @@ -215,10 +208,12 @@ private async ValueTask HandleWriteStartState(Can }); // Make sure start has completed - if (shouldAwaitStart) + if (!_started) { - await _startTask.ConfigureAwait(false); + await _startTcs.Task.ConfigureAwait(false); + _started = true; } + Console.WriteLine("Started!"); return registration; } @@ -514,6 +509,7 @@ internal static uint NativeCallbackHandler( private uint HandleEvent(ref StreamEvent evt) { uint status = MsQuicStatusCodes.Success; + Console.WriteLine("event"); try { @@ -640,23 +636,19 @@ private uint HandleStartComplete() { if (NetEventSource.IsEnabled) NetEventSource.Enter(this); - bool shouldComplete = false; + //bool shouldComplete = false; lock (_sync) { - _started = StartState.Finished; - // Check send state before completing as send cancellation is shared between start and send. if (_sendState == SendState.None) { - shouldComplete = true; + //shouldComplete = true; } - } - if (shouldComplete) - { - _sendResettableCompletionSource.Complete(MsQuicStatusCodes.Success); } + _startTcs.TrySetResult(null); + if (NetEventSource.IsEnabled) NetEventSource.Exit(this); return MsQuicStatusCodes.Success; @@ -995,14 +987,13 @@ private unsafe ValueTask SendReadOnlyMemoryListAsync( return _sendResettableCompletionSource.GetTypelessValueTask(); } - private ValueTask StartWritesAsync() + private void StartWritesAsync() { uint status = MsQuicApi.Api.StreamStartDelegate( _ptr, (uint)QUIC_STREAM_START_FLAG.ASYNC); QuicExceptionHelpers.ThrowIfFailed(status, "Could not start stream."); - return _sendResettableCompletionSource.GetValueTask(); } private void ReceiveComplete(int bufferLength) diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 8a46f42c0cdaac..2733650773c7a5 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -13,7 +13,7 @@ namespace System.Net.Quic.Tests { - [ConditionalClass(typeof(QuicConnection), nameof(QuicConnection.IsQuicSupported))] + [ConditionalClass(typeof(QuicConnection), true)] public class MsQuicTests : MsQuicTestBase { private static ReadOnlyMemory s_data = Encoding.UTF8.GetBytes("Hello world!"); From 22dc5a894bed43b9890a1d49694c472107562c03 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 12 Feb 2020 10:50:06 -0800 Subject: [PATCH 4/8] Fix calling start --- .../Implementations/MsQuic/MsQuicStream.cs | 40 ++++++++----------- .../tests/FunctionalTests/MsQuicTests.cs | 24 +++++------ 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs index be2d8d57abbbdf..6d241add3b839b 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -67,9 +67,6 @@ internal sealed class MsQuicStream : QuicStreamProvider // TODO consider using Interlocked.Exchange instead of a sync if we can avoid it. private object _sync = new object(); - - private TaskCompletionSource _startTcs = new TaskCompletionSource(); - // Creates a new MsQuicStream internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, IntPtr nativeObjPtr, bool inbound) { @@ -77,6 +74,12 @@ internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, _ptr = nativeObjPtr; + + _sendResettableCompletionSource = new ResettableCompletionSource(); + _receiveResettableCompletionSource = new ResettableCompletionSource(); + _shutdownWriteResettableCompletionSource = new ResettableCompletionSource(); + SetCallbackHandler(); + if (inbound) { _started = true; @@ -87,14 +90,8 @@ internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, { _canWrite = true; _canRead = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); + StartWrites(); } - - _sendResettableCompletionSource = new ResettableCompletionSource(); - _receiveResettableCompletionSource = new ResettableCompletionSource(); - _shutdownWriteResettableCompletionSource = new ResettableCompletionSource(); - SetCallbackHandler(); - - StartWritesAsync(); } internal override bool CanRead => _canRead; @@ -210,10 +207,9 @@ private async ValueTask HandleWriteStartState(Can // Make sure start has completed if (!_started) { - await _startTcs.Task.ConfigureAwait(false); + await _sendResettableCompletionSource.GetTypelessValueTask().ConfigureAwait(false); _started = true; } - Console.WriteLine("Started!"); return registration; } @@ -509,7 +505,6 @@ internal static uint NativeCallbackHandler( private uint HandleEvent(ref StreamEvent evt) { uint status = MsQuicStatusCodes.Success; - Console.WriteLine("event"); try { @@ -636,18 +631,20 @@ private uint HandleStartComplete() { if (NetEventSource.IsEnabled) NetEventSource.Enter(this); - //bool shouldComplete = false; + bool shouldComplete = false; lock (_sync) { // Check send state before completing as send cancellation is shared between start and send. if (_sendState == SendState.None) { - //shouldComplete = true; + shouldComplete = true; } - } - _startTcs.TrySetResult(null); + if (shouldComplete) + { + _sendResettableCompletionSource.Complete(0); + } if (NetEventSource.IsEnabled) NetEventSource.Exit(this); @@ -987,8 +984,9 @@ private unsafe ValueTask SendReadOnlyMemoryListAsync( return _sendResettableCompletionSource.GetTypelessValueTask(); } - private void StartWritesAsync() + private void StartWrites() { + Debug.Assert(!_started); uint status = MsQuicApi.Api.StreamStartDelegate( _ptr, (uint)QUIC_STREAM_START_FLAG.ASYNC); @@ -1016,12 +1014,6 @@ private void ThrowIfDisposed() } } - private enum StartState - { - None, - Finished - } - private enum ReadState { None, diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 2733650773c7a5..026a374b4d5976 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -13,7 +13,7 @@ namespace System.Net.Quic.Tests { - [ConditionalClass(typeof(QuicConnection), true)] + [ConditionalClass(typeof(QuicConnection), nameof(QuicConnection.IsQuicSupported))] public class MsQuicTests : MsQuicTestBase { private static ReadOnlyMemory s_data = Encoding.UTF8.GetBytes("Hello world!"); @@ -321,19 +321,19 @@ public async Task CallDifferentWriteMethodsWorks() Assert.Equal(24, res); } - [Fact] - public async Task GetStreamIdWithoutStartWorks() - { - using QuicListener listener = CreateQuicListener(); - using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint); + //[Fact] + //public async Task GetStreamIdWithoutStartWorks() + //{ + // using QuicListener listener = CreateQuicListener(); + // using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint); - ValueTask clientTask = clientConnection.ConnectAsync(); - using QuicConnection serverConnection = await listener.AcceptConnectionAsync(); - await clientTask; + // ValueTask clientTask = clientConnection.ConnectAsync(); + // using QuicConnection serverConnection = await listener.AcceptConnectionAsync(); + // await clientTask; - using QuicStream clientStream = clientConnection.OpenBidirectionalStream(); - Assert.Equal(0, clientStream.StreamId); - } + // using QuicStream clientStream = clientConnection.OpenBidirectionalStream(); + // Assert.Equal(0, clientStream.StreamId); + //} private static async Task CreateAndTestBidirectionalStream(QuicConnection c1, QuicConnection c2) { From c0b8b506dd83c664c921cde70673b3d360711ac6 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 12 Feb 2020 11:38:13 -0800 Subject: [PATCH 5/8] Readd test --- .../tests/FunctionalTests/MsQuicTests.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 026a374b4d5976..8a46f42c0cdaac 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -321,19 +321,19 @@ public async Task CallDifferentWriteMethodsWorks() Assert.Equal(24, res); } - //[Fact] - //public async Task GetStreamIdWithoutStartWorks() - //{ - // using QuicListener listener = CreateQuicListener(); - // using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint); - - // ValueTask clientTask = clientConnection.ConnectAsync(); - // using QuicConnection serverConnection = await listener.AcceptConnectionAsync(); - // await clientTask; - - // using QuicStream clientStream = clientConnection.OpenBidirectionalStream(); - // Assert.Equal(0, clientStream.StreamId); - //} + [Fact] + public async Task GetStreamIdWithoutStartWorks() + { + using QuicListener listener = CreateQuicListener(); + using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint); + + ValueTask clientTask = clientConnection.ConnectAsync(); + using QuicConnection serverConnection = await listener.AcceptConnectionAsync(); + await clientTask; + + using QuicStream clientStream = clientConnection.OpenBidirectionalStream(); + Assert.Equal(0, clientStream.StreamId); + } private static async Task CreateAndTestBidirectionalStream(QuicConnection c1, QuicConnection c2) { From 77f1920c8e579cbcdc9721347ad996b8fe177436 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 12 Feb 2020 13:02:07 -0800 Subject: [PATCH 6/8] Update MsQuicStream.cs --- .../src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs index 6d241add3b839b..c03ce7269fdf47 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -207,7 +207,7 @@ private async ValueTask HandleWriteStartState(Can // Make sure start has completed if (!_started) { - await _sendResettableCompletionSource.GetTypelessValueTask().ConfigureAwait(false); + await _sendResettableCompletionSource.GetTypelessValueTask(); _started = true; } From adf088e1e3ceea0b4b9c442c2cc41388c92d960e Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 12 Feb 2020 13:04:13 -0800 Subject: [PATCH 7/8] Update MsQuicStream.cs --- .../src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs index c03ce7269fdf47..32951279a7e2ae 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -74,7 +74,6 @@ internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags, _ptr = nativeObjPtr; - _sendResettableCompletionSource = new ResettableCompletionSource(); _receiveResettableCompletionSource = new ResettableCompletionSource(); _shutdownWriteResettableCompletionSource = new ResettableCompletionSource(); From a956cb4e02b60629eb60986ec0cc9dd6224786d1 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 12 Feb 2020 14:04:59 -0800 Subject: [PATCH 8/8] Update MsQuicStream.cs --- .../src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs index 32951279a7e2ae..de1f412180304f 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -642,7 +642,7 @@ private uint HandleStartComplete() if (shouldComplete) { - _sendResettableCompletionSource.Complete(0); + _sendResettableCompletionSource.Complete(MsQuicStatusCodes.Success); } if (NetEventSource.IsEnabled) NetEventSource.Exit(this);