Skip to content

Commit

Permalink
Make sure RuntimeEventSource is passed to EventListener.OnEventSource…
Browse files Browse the repository at this point in the history
…Created (dotnet/coreclr#19393)

Commit migrated from dotnet/coreclr@1c45896
  • Loading branch information
brianrob committed Aug 22, 2018
1 parent 3820494 commit a4bbaf7
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 78 deletions.
52 changes: 0 additions & 52 deletions src/coreclr/tests/src/tracing/common/RuntimeEventSource.cs

This file was deleted.

1 change: 0 additions & 1 deletion src/coreclr/tests/src/tracing/common/common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
<Compile Include="Assert.cs" />
<Compile Include="EtlFile.cs" />
<Compile Include="NetPerfFile.cs" />
<Compile Include="RuntimeEventSource.cs" />
<Compile Include="TraceControl.cs" />
<Compile Include="TraceConfiguration.cs" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,16 @@ public sealed class RuntimeEventSourceTest
{
static int Main(string[] args)
{
// Get the RuntimeEventSource.
EventSource eventSource = RuntimeEventSource.Log;

SimpleEventListener.EnableKeywords = (EventKeywords)0;
using (SimpleEventListener noEventsListener = new SimpleEventListener("NoEvents"))
{
// Enable the provider, but not any keywords, so we should get no events as long as no rundown occurs.
noEventsListener.EnableEvents(eventSource, EventLevel.Critical, (EventKeywords)(0));

// Create an EventListener.
SimpleEventListener.EnableKeywords = (EventKeywords)0x4c14fccbd;
using (SimpleEventListener listener = new SimpleEventListener("Simple"))
{
// Trigger the allocator task.
System.Threading.Tasks.Task.Run(new Action(Allocator));

// Enable events.
listener.EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)(0x4c14fccbd));

// Wait for events.
Thread.Sleep(1000);

Expand Down Expand Up @@ -73,13 +66,37 @@ internal sealed class SimpleEventListener : EventListener
{
private string m_name;

// Keep track of the set of keywords to be enabled.
public static EventKeywords EnableKeywords
{
get;
set;
}

public SimpleEventListener(string name)
{
m_name = name;
}

public int EventCount { get; private set; } = 0;

protected override void OnEventSourceCreated(EventSource eventSource)
{
if (eventSource.Name.Equals("Microsoft-Windows-DotNETRuntime"))
{
if (EnableKeywords != 0)
{
// Enable events.
EnableEvents(eventSource, EventLevel.Verbose, EnableKeywords);
}
else
{
// Enable the provider, but not any keywords, so we should get no events as long as no rundown occurs.
EnableEvents(eventSource, EventLevel.Critical, EnableKeywords);
}
}
}

protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
long osThreadId = -1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1650,6 +1650,14 @@ private static uint Rol30(uint input)

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();
Expand Down Expand Up @@ -3748,11 +3756,12 @@ private bool SelfDescribingEvents
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
}
Expand Down Expand Up @@ -3861,6 +3870,16 @@ public event EventHandler<EventSourceCreatedEventArgs> EventSourceCreated
/// </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).
Expand Down Expand Up @@ -4102,9 +4121,24 @@ internal static void AddEventSource(EventSource newEventSource)
}
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();
}
Expand Down Expand Up @@ -4185,6 +4219,14 @@ private static void RemoveReferencesToListenerInEventSources(EventListener liste
[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
Expand Down Expand Up @@ -4274,18 +4316,30 @@ private void CallBackForExistingEventSources(bool addToListenersList, EventHandl
// 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
Expand Down Expand Up @@ -4319,6 +4373,16 @@ private void CallBackForExistingEventSources(bool addToListenersList, EventHandl
/// </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>
Expand Down Expand Up @@ -4657,7 +4721,7 @@ public DateTime TimeStamp
internal set;
}

#region private
#region private
internal EventWrittenEventArgs(EventSource eventSource)
{
m_eventSource = eventSource;
Expand Down

0 comments on commit a4bbaf7

Please sign in to comment.