Fix data race on incoming MsQuicStream abort event (#69483)
authorRadek Zikmund <32671551+rzikm@users.noreply.github.com>
Wed, 18 May 2022 16:15:20 +0000 (18:15 +0200)
committerGitHub <noreply@github.com>
Wed, 18 May 2022 16:15:20 +0000 (18:15 +0200)
* Fix data race on MsQuicStream abort

* fixup! Fix data race on MsQuicStream abort

src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs

index 17c1e52..622df81 100644 (file)
@@ -329,7 +329,8 @@ namespace System.Net.Quic.Implementations.MsQuic
             {
                 throw new InvalidOperationException(SR.net_quic_writing_notallowed);
             }
-            if (_state.SendState == SendState.Aborted)
+            // Use Volatile.Read to ensure we read the actual SendErrorCode set by the racing callback thread.
+            if ((SendState)Volatile.Read(ref Unsafe.As<SendState, int>(ref _state.SendState)) == SendState.Aborted)
             {
                 if (_state.SendErrorCode != -1)
                 {
@@ -1112,8 +1113,10 @@ namespace System.Net.Quic.Implementations.MsQuic
                     shouldShutdownWriteComplete = true;
                 }
 
-                state.SendState = SendState.Aborted;
                 state.SendErrorCode = (long)streamEvent.PEER_RECEIVE_ABORTED.ErrorCode;
+                // make sure the SendErrorCode above is commited to memory before we assign the state. This
+                // ensures that the code is read correctly in SetupWriteStartState when checking without lock
+                Volatile.Write(ref Unsafe.As<SendState, int>(ref state.SendState), (int)SendState.Aborted);
             }
 
             if (shouldSendComplete)