Skip to content

Commit 9aa55ee

Browse files
authored
Fixes that repeatedly adding unhandled event handler to TraceLog to real time session conversion (#2159)
1 parent f9303b1 commit 9aa55ee

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

src/TraceEvent/TraceLog.cs

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,25 @@ private unsafe TraceLog(TraceEventDispatcher source)
749749
rawEventSourceToConvert = source;
750750
SetupCallbacks(rawEventSourceToConvert);
751751
rawEventSourceToConvert.unhandledEventTemplate.traceEventSource = this; // Make everything point to the log as its source.
752+
753+
// Self describing metadata doesn't make it to realTimeSource because TraceLog overwrites the event's extended data.
754+
// To address this, we use the event from the raw source, which contains the metadata,
755+
// and convert it to a template that can be registered with realTimeSource.
756+
realTimeSource.RegisterUnhandledEventImpl(te =>
757+
{
758+
var toSend = realTimeEvent;
759+
if (toSend == null)
760+
{
761+
return false;
762+
}
763+
if (toSend.containsSelfDescribingMetadata)
764+
{
765+
var template = toSend.CloneToTemplate();
766+
realTimeSource.Dynamic.OnNewEventDefintion(template, true);
767+
return true;
768+
}
769+
return false;
770+
});
752771
}
753772

754773
private unsafe void onAllEventsRealTime(TraceEvent data)
@@ -813,24 +832,20 @@ private static void RemoveAllButLastEntries<T>(ref GrowableArray<T> growableArra
813832
/// </summary>
814833
private unsafe void DispatchClonedEvent(TraceEvent toSend)
815834
{
816-
// Self describing metadata doesn't make it to realTimeSource because TraceLog overwrites the event's extended data.
817-
// To address this, we use the event from the raw source, which contains the metadata,
818-
// and convert it to a template that can be registered with realTimeSource.
819-
realTimeSource.RegisterUnhandledEventImpl(te =>
835+
realTimeEvent = toSend;
836+
TraceEvent eventInRealTimeSource = null;
837+
try
820838
{
821-
if (toSend.containsSelfDescribingMetadata)
822-
{
823-
var template = toSend.CloneToTemplate();
824-
realTimeSource.Dynamic.OnNewEventDefintion(template, true);
825-
return true;
826-
}
827-
return false;
828-
});
829-
TraceEvent eventInRealTimeSource = realTimeSource.Lookup(toSend.eventRecord);
830-
eventInRealTimeSource.userData = toSend.userData;
831-
eventInRealTimeSource.eventIndex = toSend.eventIndex; // Lookup assigns the EventIndex, but we want to keep the original.
832-
eventInRealTimeSource.myBuffer = toSend.myBuffer;
833-
realTimeSource.Dispatch(eventInRealTimeSource);
839+
eventInRealTimeSource = realTimeSource.Lookup(toSend.eventRecord);
840+
eventInRealTimeSource.userData = toSend.userData;
841+
eventInRealTimeSource.eventIndex = toSend.eventIndex; // Lookup assigns the EventIndex, but we want to keep the original.
842+
eventInRealTimeSource.myBuffer = toSend.myBuffer;
843+
realTimeSource.Dispatch(eventInRealTimeSource);
844+
}
845+
finally
846+
{
847+
realTimeEvent = null;
848+
}
834849

835850
// Optimization, remove 'toSend' from the finalization queue.
836851
Debug.Assert(toSend.myBuffer != IntPtr.Zero);
@@ -4445,6 +4460,7 @@ private struct QueueEntry
44454460

44464461
internal TraceLogEventSource realTimeSource; // used to call back in real time case.
44474462
private Queue<QueueEntry> realTimeQueue; // We have to wait a bit to hook up stacks, so we put real time entries in the queue
4463+
private TraceEvent realTimeEvent; // The current event being processed.
44484464

44494465
// These can ONLY be accessed by the thread calling RealTimeEventSource.Process();
44504466
private Timer realTimeFlushTimer; // Ensures the queue gets flushed even if there are no incoming events.

0 commit comments

Comments
 (0)