Skip to content

Commit c945d04

Browse files
committed
don't call validate while messing with eventlistener list, and move call to disableevents out of the main loop
Update EventSource.cs
1 parent 84654a6 commit c945d04

File tree

1 file changed

+44
-9
lines changed
  • src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing

1 file changed

+44
-9
lines changed

src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs

+44-9
Original file line numberDiff line numberDiff line change
@@ -4222,18 +4222,33 @@ internal static void DisposeOnShutdown()
42224222
// If an EventListener calls Dispose without calling DisableEvents first we want to issue the Disable command now
42234223
private static void CallDisableEventsIfNecessary(EventDispatcher eventDispatcher, EventSource eventSource)
42244224
{
4225-
if (eventDispatcher.m_EventEnabled == null)
4225+
#if DEBUG
4226+
// Disable validation of EventSource/EventListener connections in case a call to EventSource.AddListener
4227+
// causes a recursive call into this method.
4228+
bool previousValue = s_ConnectingEventSourcesAndListener;
4229+
s_ConnectingEventSourcesAndListener = true;
4230+
try
42264231
{
4227-
return;
4228-
}
4232+
#endif
4233+
if (eventDispatcher.m_EventEnabled == null)
4234+
{
4235+
return;
4236+
}
42294237

4230-
for (int i = 0; i < eventDispatcher.m_EventEnabled.Length; ++i)
4231-
{
4232-
if (eventDispatcher.m_EventEnabled[i])
4238+
for (int i = 0; i < eventDispatcher.m_EventEnabled.Length; ++i)
42334239
{
4234-
eventDispatcher.m_Listener.DisableEvents(eventSource);
4240+
if (eventDispatcher.m_EventEnabled[i])
4241+
{
4242+
eventDispatcher.m_Listener.DisableEvents(eventSource);
4243+
}
42354244
}
4245+
#if DEBUG
4246+
}
4247+
finally
4248+
{
4249+
s_ConnectingEventSourcesAndListener = previousValue;
42364250
}
4251+
#endif
42374252
}
42384253

42394254
/// <summary>
@@ -4247,6 +4262,27 @@ private static void RemoveReferencesToListenerInEventSources(EventListener liste
42474262
Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
42484263
// Foreach existing EventSource in the appdomain
42494264
Debug.Assert(s_EventSources != null);
4265+
4266+
// First pass to call DisableEvents
4267+
foreach (WeakReference<EventSource> eventSourceRef in s_EventSources)
4268+
{
4269+
if (eventSourceRef.TryGetTarget(out EventSource? eventSource))
4270+
{
4271+
EventDispatcher? cur = eventSource.m_Dispatchers;
4272+
while (cur != null)
4273+
{
4274+
if (cur.m_Listener == listenerToRemove)
4275+
{
4276+
CallDisableEventsIfNecessary(cur!, eventSource);
4277+
}
4278+
4279+
cur = cur.m_Next;
4280+
}
4281+
}
4282+
}
4283+
4284+
// DisableEvents can call back to user code and we have to start over since s_EventSources and
4285+
// eventSource.m_Dispatchers could have mutated
42504286
foreach (WeakReference<EventSource> eventSourceRef in s_EventSources)
42514287
{
42524288
if (eventSourceRef.TryGetTarget(out EventSource? eventSource))
@@ -4255,7 +4291,6 @@ private static void RemoveReferencesToListenerInEventSources(EventListener liste
42554291
// Is the first output dispatcher the dispatcher we are removing?
42564292
if (eventSource.m_Dispatchers.m_Listener == listenerToRemove)
42574293
{
4258-
CallDisableEventsIfNecessary(eventSource.m_Dispatchers!, eventSource);
42594294
eventSource.m_Dispatchers = eventSource.m_Dispatchers.m_Next;
42604295
}
42614296
else
@@ -4272,7 +4307,6 @@ private static void RemoveReferencesToListenerInEventSources(EventListener liste
42724307
}
42734308
if (cur.m_Listener == listenerToRemove)
42744309
{
4275-
CallDisableEventsIfNecessary(cur!, eventSource);
42764310
prev.m_Next = cur.m_Next; // Remove entry.
42774311
break;
42784312
}
@@ -4288,6 +4322,7 @@ private static void RemoveReferencesToListenerInEventSources(EventListener liste
42884322
#endif // FEATURE_PERFTRACING
42894323
}
42904324

4325+
42914326
/// <summary>
42924327
/// Checks internal consistency of EventSources/Listeners.
42934328
/// </summary>

0 commit comments

Comments
 (0)