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);
}
EventPipeSessionInfo sessionInfo;
unsafe
{
- if (!EventPipeInternal.GetSessionInfo(m_sessionID, &sessionInfo))
+ if (!EventPipeInternal.GetSessionInfo(sessionID, &sessionInfo))
{
Debug.Fail("GetSessionInfo returned false.");
}
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)
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)
}
}
- 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>