using System.Globalization;
using System.Numerics;
using System.Runtime.InteropServices;
+using System.Threading;
#if ES_BUILD_STANDALONE
using Microsoft.Win32;
// deadlocks in race conditions (dispose racing with an ETW command).
//
// We solve by Unregistering after releasing the EventListenerLock.
+ Debug.Assert(!Monitor.IsEntered(EventListener.EventListenersLock));
if (registrationHandle != 0)
EventUnregister(registrationHandle);
}
return;
}
+ // Do not invoke Dispose under the lock as this can lead to a deadlock.
+ // See https://github.com/dotnet/runtime/issues/48342 for details.
+ Debug.Assert(!Monitor.IsEntered(EventListener.EventListenersLock));
+
if (disposing)
{
#if FEATURE_MANAGED_ETW
#endif
{
Debug.Assert(EventSource.IsSupported);
-
+ List<EventSource> sourcesToDispose = new List<EventSource>();
lock (EventListenersLock)
{
Debug.Assert(s_EventSources != null);
foreach (WeakReference<EventSource> esRef in s_EventSources)
{
if (esRef.TryGetTarget(out EventSource? es))
- es.Dispose();
+ {
+ sourcesToDispose.Add(es);
+ }
}
}
+
+ // Do not invoke Dispose under the lock as this can lead to a deadlock.
+ // See https://github.com/dotnet/runtime/issues/48342 for details.
+ Debug.Assert(!Monitor.IsEntered(EventListenersLock));
+ foreach (EventSource es in sourcesToDispose)
+ {
+ es.Dispose();
+ }
}
/// <summary>