Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian Robbins <brianrob@microsoft.com>2018-08-23 01:07:52 +0300
committerJan Kotas <jkotas@microsoft.com>2018-08-23 09:00:30 +0300
commit7c95acb9bfa0bd7238196b7a48df59d9658ef276 (patch)
tree4a96e517f5cd5e21b56f471f5dbcb98166b5b446 /src
parent2d4981ac9e35d34856006b7429f827b5316aaa1b (diff)
Make sure RuntimeEventSource is passed to EventListener.OnEventSourceCreated (#19393)
Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Diffstat (limited to 'src')
-rw-r--r--src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs96
1 files changed, 80 insertions, 16 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
index 5c05bf831..9784a34d9 100644
--- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
+++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
@@ -1650,6 +1650,14 @@ namespace System.Diagnostics.Tracing
private static Guid GenerateGuidFromName(string name)
{
+ if (namespaceBytes == null)
+ {
+ namespaceBytes = new byte[] {
+ 0x48, 0x2C, 0x2D, 0xB2, 0xC3, 0x90, 0x47, 0xC8,
+ 0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB,
+ };
+ }
+
byte[] bytes = Encoding.BigEndianUnicode.GetBytes(name);
var hash = new Sha1ForNonSecretPurposes();
hash.Start();
@@ -3748,11 +3756,12 @@ namespace System.Diagnostics.Tracing
internal const string s_ActivityStartSuffix = "Start";
internal const string s_ActivityStopSuffix = "Stop";
+ // WARNING: Do not depend upon initialized statics during creation of EventSources, as it is possible for creation of an EventSource to trigger
+ // creation of yet another EventSource. When this happens, these statics may not yet be initialized.
+ // Rather than depending on initialized statics, use lazy initialization to ensure that the statics are initialized exactly when they are needed.
+
// used for generating GUID from eventsource name
- private static readonly byte[] namespaceBytes = new byte[] {
- 0x48, 0x2C, 0x2D, 0xB2, 0xC3, 0x90, 0x47, 0xC8,
- 0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB,
- };
+ private static byte[] namespaceBytes;
#endregion
}
@@ -3861,6 +3870,16 @@ namespace System.Diagnostics.Tracing
/// </summary>
public event EventHandler<EventWrittenEventArgs> EventWritten;
+ static EventListener()
+ {
+#if FEATURE_PERFTRACING
+ // Ensure that RuntimeEventSource is initialized so that EventListeners get an opportunity to subscribe to its events.
+ // This is required because RuntimeEventSource never emit events on its own, and thus will never be initialized
+ // in the normal way that EventSources are initialized.
+ GC.KeepAlive(RuntimeEventSource.Log);
+#endif // FEATURE_PERFTRACING
+ }
+
/// <summary>
/// Create a new EventListener in which all events start off turned off (use EnableEvents to turn
/// them on).
@@ -4102,9 +4121,24 @@ namespace System.Diagnostics.Tracing
}
newEventSource.m_id = newIndex;
- // Add every existing dispatcher to the new EventSource
- for (EventListener listener = s_Listeners; listener != null; listener = listener.m_Next)
- newEventSource.AddListener(listener);
+#if DEBUG
+ // Disable validation of EventSource/EventListener connections in case a call to EventSource.AddListener
+ // causes a recursive call into this method.
+ bool previousValue = s_ConnectingEventSourcesAndListener;
+ s_ConnectingEventSourcesAndListener = true;
+ try
+ {
+#endif
+ // Add every existing dispatcher to the new EventSource
+ for (EventListener listener = s_Listeners; listener != null; listener = listener.m_Next)
+ newEventSource.AddListener(listener);
+#if DEBUG
+ }
+ finally
+ {
+ s_ConnectingEventSourcesAndListener = previousValue;
+ }
+#endif
Validate();
}
@@ -4185,6 +4219,14 @@ namespace System.Diagnostics.Tracing
[Conditional("DEBUG")]
internal static void Validate()
{
+#if DEBUG
+ // Don't run validation code if we're in the middle of modifying the connections between EventSources and EventListeners.
+ if (s_ConnectingEventSourcesAndListener)
+ {
+ return;
+ }
+#endif
+
lock (EventListenersLock)
{
// Get all listeners
@@ -4274,18 +4316,30 @@ namespace System.Diagnostics.Tracing
// is created.
WeakReference[] eventSourcesSnapshot = s_EventSources.ToArray();
- for (int i = 0; i < eventSourcesSnapshot.Length; i++)
+#if DEBUG
+ bool previousValue = s_ConnectingEventSourcesAndListener;
+ s_ConnectingEventSourcesAndListener = true;
+ try
{
- WeakReference eventSourceRef = eventSourcesSnapshot[i];
- EventSource eventSource = eventSourceRef.Target as EventSource;
- if (eventSource != null)
+#endif
+ for (int i = 0; i < eventSourcesSnapshot.Length; i++)
{
- EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs();
- args.EventSource = eventSource;
- callback(this, args);
+ WeakReference eventSourceRef = eventSourcesSnapshot[i];
+ EventSource eventSource = eventSourceRef.Target as EventSource;
+ if (eventSource != null)
+ {
+ EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs();
+ args.EventSource = eventSource;
+ callback(this, args);
+ }
}
+#if DEBUG
}
-
+ finally
+ {
+ s_ConnectingEventSourcesAndListener = previousValue;
+ }
+#endif
Validate();
}
finally
@@ -4319,6 +4373,16 @@ namespace System.Diagnostics.Tracing
/// </summary>
private static bool s_CreatingListener = false;
+#if DEBUG
+ /// <summary>
+ /// Used to disable validation of EventSource and EventListener connectivity.
+ /// This is needed when an EventListener is in the middle of being published to all EventSources
+ /// and another EventSource is created as part of the process.
+ /// </summary>
+ [ThreadStatic]
+ private static bool s_ConnectingEventSourcesAndListener = false;
+#endif
+
/// <summary>
/// Used to register AD/Process shutdown callbacks.
/// </summary>
@@ -4657,7 +4721,7 @@ namespace System.Diagnostics.Tracing
internal set;
}
- #region private
+#region private
internal EventWrittenEventArgs(EventSource eventSource)
{
m_eventSource = eventSource;