Skip to content

Commit bf47f0d

Browse files
authored
[Release/7.0] Port EventCounters multi session support to 7.0 (#84679)
1 parent cd73b4f commit bf47f0d

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/CounterGroup.cs

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,46 @@ private void RegisterCommandCallback()
4646

4747
private void OnEventSourceCommand(object? sender, EventCommandEventArgs e)
4848
{
49-
if (e.Command == EventCommand.Enable || e.Command == EventCommand.Update)
50-
{
51-
Debug.Assert(e.Arguments != null);
49+
// Should only be enable or disable
50+
Debug.Assert(e.Command == EventCommand.Enable || e.Command == EventCommand.Disable);
5251

53-
if (e.Arguments.TryGetValue("EventCounterIntervalSec", out string? valueStr) && float.TryParse(valueStr, out float value))
52+
lock (s_counterGroupLock) // Lock the CounterGroup
53+
{
54+
if (e.Command == EventCommand.Enable || e.Command == EventCommand.Update)
5455
{
55-
lock (s_counterGroupLock) // Lock the CounterGroup
56+
Debug.Assert(e.Arguments != null);
57+
58+
if (!e.Arguments.TryGetValue("EventCounterIntervalSec", out string? valueStr)
59+
|| !float.TryParse(valueStr, out float intervalValue))
5660
{
57-
EnableTimer(value);
61+
// Command is Enable but no EventCounterIntervalSec arg so ignore
62+
return;
5863
}
64+
65+
EnableTimer(intervalValue);
5966
}
60-
}
61-
else if (e.Command == EventCommand.Disable)
62-
{
63-
lock (s_counterGroupLock)
67+
else if (e.Command == EventCommand.Disable)
6468
{
65-
DisableTimer();
69+
// Since we allow sessions to send multiple Enable commands to update the interval, we cannot
70+
// rely on ref counting to determine when to enable and disable counters. You will get an arbitrary
71+
// number of Enables and one Disable per session.
72+
//
73+
// Previously we would turn off counters when we received any Disable command, but that meant that any
74+
// session could turn off counters for all other sessions. To get to a good place we now will only
75+
// turn off counters once the EventSource that provides the counters is disabled. We can then end up
76+
// keeping counters on too long in certain circumstances - if one session enables counters, then a second
77+
// session enables the EventSource but not counters we will stay on until both sessions terminate, even
78+
// if the first session terminates first.
79+
if (!_eventSource.IsEnabled())
80+
{
81+
DisableTimer();
82+
}
6683
}
84+
85+
Debug.Assert((s_counterGroupEnabledList == null && !_eventSource.IsEnabled())
86+
|| (_eventSource.IsEnabled() && s_counterGroupEnabledList!.Contains(this))
87+
|| (_pollingIntervalInMilliseconds == 0 && !s_counterGroupEnabledList!.Contains(this))
88+
|| (!_eventSource.IsEnabled() && !s_counterGroupEnabledList!.Contains(this)));
6789
}
6890
}
6991

src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,9 +2645,6 @@ internal void DoCommand(EventCommandEventArgs commandArgs)
26452645
m_eventSourceEnabled = true;
26462646
}
26472647

2648-
this.OnEventCommand(commandArgs);
2649-
this.m_eventCommandExecuted?.Invoke(this, commandArgs);
2650-
26512648
if (!commandArgs.enable)
26522649
{
26532650
// If we are disabling, maybe we can turn on 'quick checks' to filter
@@ -2679,6 +2676,9 @@ internal void DoCommand(EventCommandEventArgs commandArgs)
26792676
m_eventSourceEnabled = false;
26802677
}
26812678
}
2679+
2680+
this.OnEventCommand(commandArgs);
2681+
this.m_eventCommandExecuted?.Invoke(this, commandArgs);
26822682
}
26832683
else
26842684
{

0 commit comments

Comments
 (0)