-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Defuse throttled_func when it's accidentally engaged #18235
Conversation
BTW there's a good chance that this bug was caused by a miscompilation. Lately I've had A LOT of crashes in random code which go away with a clean build. To be fair, I'm using the latest preview version of VS, but there may be some fun times coming for us. |
decltype(_pendingRunArgs) args; | ||
{ | ||
std::unique_lock guard{ _lock }; | ||
args = std::exchange(_pendingRunArgs, std::nullopt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As suggested by Dustin, this now uses std::exchange
.
{ | ||
_trailing_edge(); | ||
} | ||
_timer_callback(nullptr, this, nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading this code I've realized that I can ever so slightly reduce the binary size by moving _trailing_edge
into the _timer_callback
and calling _timer_callback
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It depends honestly. If all of timer_callback is larger and less deduplicatable with COMDAT folding, it could be larger overall.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I think I see what you mean. It does have the additional benefit that it swallows the exception, just like the regular timer callback. This makes it more predictable IMO, because it now behaves identical.
This change prevents
throttled_func
from reading uninitialized memoryunder some yet-unkown circumstances. The tl;dr is:
This simply moves the callback invocation into the storage.
That way we can centrally avoid invoking the callback accidentally.