Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EventSource] Block EventCommandExecuted callback during initialization #105341

Merged
merged 3 commits into from
Jul 26, 2024

Conversation

mdh1418
Copy link
Member

@mdh1418 mdh1418 commented Jul 23, 2024

During managed startup, the managed EventSource RuntimeEventSource is initialized, kicking off EventSource initialization where all deferred commands m_deferredCommands for that EventSource instance are processed one at a time at the end of EventSource.Initialize.

However, should a derived EventSource set its callback EventCommandExecuted within its OnEventCommand, then because of the decision to invoke the callback on all deferred commands, the callback will be invoked before all deferred commands could be initially processed in EventSource.Initialize.

CounterGroup registers its callback during construction, so should multiple events be sent to RuntimeEventSource during initialization (e.g. m_deferredCommands = [ Update, Update, Update, ... ]), then because RuntimeEventSource initializes multiple event counters once the deferred command is processed at the end of EventSource.Initialize() ((i.e. m_deferredCommands = [ Enable, Update, Update, ... ]), then the callback is invoked on all deferred commands before they are converted from Update.
This leads to an assertion error as demonstrated by

EventSource[2000003047]Invoke deferred command on this value:System.Diagnostics.Tracing.EventCommandEventArgs(-1391687009 Command = Enable)
EventSource[2000003047]Invoke deferred command on this value:System.Diagnostics.Tracing.EventCommandEventArgs(663802102 Command = Update)

in #96324 (comment).

This PR aims to avoid double-invocations of the same callback m_eventCommandExecuted during EventSource.Initialize should the more-derived EventSource class set-up its EventCommandExecuted callback within its OnEventCommand.

To do so, we defer invoking the EventCommandExecuted callback on deferred commands until after all deferred commands are first-processed during initialization.

Fixes #94964
Fixes #96324
Fixes #99497
Fixes #92519

Copy link
Contributor

Tagging subscribers to this area: @tarekgh, @tommcdon, @pjanotti
See info in area-owners.md if you want to be subscribed.

Copy link
Member

@tommcdon tommcdon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Member

@noahfalk noahfalk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fix looks like it works around the issue which is OK, but I think we could fix the root cause fairly easily. Comments inline.

Guard EventCommandExecuted deferred commands callbacks with
EventSource initialization to prevent CounterGroup's callback
registration from seeing unexpected commands
Copy link
Member

@noahfalk noahfalk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionally the code change looks fine but I recommended some tweaks to the comments.

Copy link
Member

@davmason davmason left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tracking this down!

@github-actions github-actions bot locked and limited conversation to collaborators Aug 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.