@@ -1649,6 +1649,14 @@ private static uint Rol30(uint input)
1649
1649
1650
1650
private static Guid GenerateGuidFromName ( string name )
1651
1651
{
1652
+ if ( namespaceBytes == null )
1653
+ {
1654
+ namespaceBytes = new byte [ ] {
1655
+ 0x48 , 0x2C , 0x2D , 0xB2 , 0xC3 , 0x90 , 0x47 , 0xC8 ,
1656
+ 0x87 , 0xF8 , 0x1A , 0x15 , 0xBF , 0xC1 , 0x30 , 0xFB ,
1657
+ } ;
1658
+ }
1659
+
1652
1660
byte [ ] bytes = Encoding . BigEndianUnicode . GetBytes ( name ) ;
1653
1661
var hash = new Sha1ForNonSecretPurposes ( ) ;
1654
1662
hash . Start ( ) ;
@@ -3734,11 +3742,12 @@ private bool SelfDescribingEvents
3734
3742
internal const string s_ActivityStartSuffix = "Start";
3735
3743
internal const string s_ActivityStopSuffix = "Stop";
3736
3744
3745
+ // WARNING: Do not depend upon initialized statics during creation of EventSources, as it is possible for creation of an EventSource to trigger
3746
+ // creation of yet another EventSource. When this happens, these statics may not yet be initialized.
3747
+ // Rather than depending on initialized statics, use lazy initialization to ensure that the statics are initialized exactly when they are needed.
3748
+
3737
3749
// used for generating GUID from eventsource name
3738
- private static readonly byte [ ] namespaceBytes = new byte [ ] {
3739
- 0x48 , 0x2C , 0x2D , 0xB2 , 0xC3 , 0x90 , 0x47 , 0xC8 ,
3740
- 0x87 , 0xF8 , 0x1A , 0x15 , 0xBF , 0xC1 , 0x30 , 0xFB ,
3741
- } ;
3750
+ private static byte [ ] namespaceBytes;
3742
3751
3743
3752
#endregion
3744
3753
}
@@ -3847,6 +3856,16 @@ public event EventHandler<EventSourceCreatedEventArgs> EventSourceCreated
3847
3856
/// </summary>
3848
3857
public event EventHandler< EventWrittenEventArgs> EventWritten;
3849
3858
3859
+ static EventListener( )
3860
+ {
3861
+ #if FEATURE_PERFTRACING
3862
+ // Ensure that RuntimeEventSource is initialized so that EventListeners get an opportunity to subscribe to its events.
3863
+ // This is required because RuntimeEventSource never emit events on its own, and thus will never be initialized
3864
+ // in the normal way that EventSources are initialized.
3865
+ GC. KeepAlive( RuntimeEventSource. Log) ;
3866
+ #endif // FEATURE_PERFTRACING
3867
+ }
3868
+
3850
3869
/// <summary>
3851
3870
/// Create a new EventListener in which all events start off turned off (use EnableEvents to turn
3852
3871
/// them on).
@@ -4082,9 +4101,24 @@ internal static void AddEventSource(EventSource newEventSource)
4082
4101
}
4083
4102
newEventSource. m_id = newIndex;
4084
4103
4085
- // Add every existing dispatcher to the new EventSource
4086
- for ( EventListener listener = s_Listeners; listener != null ; listener = listener. m_Next)
4087
- newEventSource. AddListener( listener) ;
4104
+ #if DEBUG
4105
+ // Disable validation of EventSource/EventListener connections in case a call to EventSource.AddListener
4106
+ // causes a recursive call into this method.
4107
+ bool previousValue = s_ConnectingEventSourcesAndListener;
4108
+ s_ConnectingEventSourcesAndListener = true;
4109
+ try
4110
+ {
4111
+ #endif
4112
+ // Add every existing dispatcher to the new EventSource
4113
+ for ( EventListener listener = s_Listeners; listener != null ; listener = listener. m_Next)
4114
+ newEventSource. AddListener( listener) ;
4115
+ #if DEBUG
4116
+ }
4117
+ finally
4118
+ {
4119
+ s_ConnectingEventSourcesAndListener = previousValue;
4120
+ }
4121
+ #endif
4088
4122
4089
4123
Validate( ) ;
4090
4124
}
@@ -4165,6 +4199,14 @@ private static void RemoveReferencesToListenerInEventSources(EventListener liste
4165
4199
[ Conditional( "DEBUG") ]
4166
4200
internal static void Validate( )
4167
4201
{
4202
+ #if DEBUG
4203
+ // Don't run validation code if we're in the middle of modifying the connections between EventSources and EventListeners.
4204
+ if ( s_ConnectingEventSourcesAndListener)
4205
+ {
4206
+ return ;
4207
+ }
4208
+ #endif
4209
+
4168
4210
lock ( EventListenersLock)
4169
4211
{
4170
4212
// Get all listeners
@@ -4254,18 +4296,30 @@ private void CallBackForExistingEventSources(bool addToListenersList, EventHandl
4254
4296
// is created.
4255
4297
WeakReference[ ] eventSourcesSnapshot = s_EventSources. ToArray( ) ;
4256
4298
4257
- for ( int i = 0 ; i < eventSourcesSnapshot. Length; i++ )
4299
+ #if DEBUG
4300
+ bool previousValue = s_ConnectingEventSourcesAndListener;
4301
+ s_ConnectingEventSourcesAndListener = true;
4302
+ try
4258
4303
{
4259
- WeakReference eventSourceRef = eventSourcesSnapshot[ i] ;
4260
- EventSource eventSource = eventSourceRef. Target as EventSource;
4261
- if ( eventSource != null )
4304
+ #endif
4305
+ for ( int i = 0 ; i < eventSourcesSnapshot. Length; i++ )
4262
4306
{
4263
- EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs( ) ;
4264
- args. EventSource = eventSource;
4265
- callback( this , args) ;
4307
+ WeakReference eventSourceRef = eventSourcesSnapshot[ i] ;
4308
+ EventSource eventSource = eventSourceRef. Target as EventSource;
4309
+ if ( eventSource != null )
4310
+ {
4311
+ EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs( ) ;
4312
+ args. EventSource = eventSource;
4313
+ callback( this , args) ;
4314
+ }
4266
4315
}
4316
+ #if DEBUG
4267
4317
}
4268
-
4318
+ finally
4319
+ {
4320
+ s_ConnectingEventSourcesAndListener = previousValue;
4321
+ }
4322
+ #endif
4269
4323
Validate( ) ;
4270
4324
}
4271
4325
finally
@@ -4299,6 +4353,16 @@ private void CallBackForExistingEventSources(bool addToListenersList, EventHandl
4299
4353
/// </summary>
4300
4354
private static bool s_CreatingListener = false;
4301
4355
4356
+ #if DEBUG
4357
+ /// <summary>
4358
+ /// Used to disable validation of EventSource and EventListener connectivity.
4359
+ /// This is needed when an EventListener is in the middle of being published to all EventSources
4360
+ /// and another EventSource is created as part of the process.
4361
+ /// </summary>
4362
+ [ ThreadStatic]
4363
+ private static bool s_ConnectingEventSourcesAndListener = false;
4364
+ #endif
4365
+
4302
4366
/// <summary>
4303
4367
/// Used to register AD/Process shutdown callbacks.
4304
4368
/// </summary>
@@ -4637,7 +4701,7 @@ public DateTime TimeStamp
4637
4701
internal set ;
4638
4702
}
4639
4703
4640
- #region private
4704
+ #region private
4641
4705
internal EventWrittenEventArgs( EventSource eventSource)
4642
4706
{
4643
4707
m_eventSource = eventSource;
0 commit comments