Update EventPipeEventDispatcher.cs (#92912)
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Tue, 3 Oct 2023 19:45:25 +0000 (12:45 -0700)
committerGitHub <noreply@github.com>
Tue, 3 Oct 2023 19:45:25 +0000 (12:45 -0700)
Co-authored-by: David Mason <davmason@microsoft.com>
src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs

index 708c5af..030560b 100644 (file)
@@ -103,8 +103,8 @@ namespace System.Diagnostics.Tracing
                 new EventPipeProviderConfiguration(NativeRuntimeEventSource.EventSourceName, (ulong)aggregatedKeywords, (uint)enableLevel, null)
             };
 
-            m_sessionID = EventPipeInternal.Enable(null, EventPipeSerializationFormat.NetTrace, DefaultEventListenerCircularMBSize, providerConfiguration);
-            if (m_sessionID == 0)
+            ulong sessionID = EventPipeInternal.Enable(null, EventPipeSerializationFormat.NetTrace, DefaultEventListenerCircularMBSize, providerConfiguration);
+            if (sessionID == 0)
             {
                 throw new EventSourceException(SR.EventSource_CouldNotEnableEventPipe);
             }
@@ -113,7 +113,7 @@ namespace System.Diagnostics.Tracing
             EventPipeSessionInfo sessionInfo;
             unsafe
             {
-                if (!EventPipeInternal.GetSessionInfo(m_sessionID, &sessionInfo))
+                if (!EventPipeInternal.GetSessionInfo(sessionID, &sessionInfo))
                 {
                     Debug.Fail("GetSessionInfo returned false.");
                 }
@@ -124,8 +124,11 @@ namespace System.Diagnostics.Tracing
             long syncTimeQPC = sessionInfo.StartTimeStamp;
             long timeQPCFrequency = sessionInfo.TimeStampFrequency;
 
+            Debug.Assert(Volatile.Read(ref m_sessionID) == 0);
+            Volatile.Write(ref m_sessionID, sessionID);
+
             // Start the dispatch task.
-            StartDispatchTask(m_sessionID, syncTimeUtc, syncTimeQPC, timeQPCFrequency);
+            StartDispatchTask(sessionID, syncTimeUtc, syncTimeQPC, timeQPCFrequency);
         }
 
         private void StartDispatchTask(ulong sessionID, DateTime syncTimeUtc, long syncTimeQPC, long timeQPCFrequency)
@@ -147,10 +150,11 @@ namespace System.Diagnostics.Tracing
                 return;
             }
 
-            Debug.Assert(m_sessionID != 0);
+            ulong sessionID = Volatile.Read(ref m_sessionID);
+            Debug.Assert(sessionID != 0);
             m_dispatchTaskCancellationSource.Cancel();
-            EventPipeInternal.SignalSession(m_sessionID);
-            m_sessionID = 0;
+            EventPipeInternal.SignalSession(sessionID);
+            Volatile.Write(ref m_sessionID, 0);
         }
 
         private unsafe void DispatchEventsToEventListeners(ulong sessionID, DateTime syncTimeUtc, long syncTimeQPC, long timeQPCFrequency, Task? previousDispatchTask, CancellationToken token)
@@ -190,12 +194,17 @@ namespace System.Diagnostics.Tracing
                 }
             }
 
-            lock (m_dispatchControlLock)
+            // Wait for SignalSession() to be called before we call disable, otherwise
+            // the SignalSession() call could be on a disabled session.
+            SpinWait sw = default;
+            while (Volatile.Read(ref m_sessionID) == sessionID)
             {
-                // Disable the old session. This can happen asynchronously since we aren't using the old session
-                // anymore. We take the lock to make sure we don't call SignalSession on an invalid session ID.
-                EventPipeInternal.Disable(sessionID);
+                sw.SpinOnce();
             }
+
+            // Disable the old session. This can happen asynchronously since we aren't using the old session
+            // anymore.
+            EventPipeInternal.Disable(sessionID);
         }
 
         /// <summary>