fix: clone wakers outside state locks - #245
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
WaitSetaccept an ownedWakerso it cannot clone user-provided wakers while a primitive state lock is heldwill_wake,register,unregister, anddrain, and consistently name each future's slot identity aWakerTokenDesign Notes
A
RawWakerclone, drop, or wake callback is arbitrary user code and may reenter the primitive using it.WaitSettherefore only moves already owned wakers under its owner's lock; callers clone before locking and process every waker returned byregister,unregister, ordrainafter unlocking.WakerTokenidentifies one cancellable waiter slot without implying ownership of the waker itself. Itsepochinvalidates tokens retained by futures after a non-empty drain, which prevents them from aliasing slots reused by later waiters.epochis intentionally distinct from Barrier's public-domain generation counter.Completion and Broadcast retain their repeated-ready and buffered-ready fast paths with a two-phase check. Barrier and Watch prepare one waker before locking because a wait normally parks once, while Countdown keeps its existing atomic ready check before cloning. Follow-up #246 tracks whether Completion's monotonic status can support a simpler registration path without regressing its ready path.
Targeted benchmarks against
mainshowed no consistent regression beyond run-to-run noise.Tests
cargo x checkcargo x testcargo x lintMIRIFLAGS='-Zmiri-strict-provenance -Zmiri-symbolic-alignment-check -Zmiri-many-seeds=0..4' cargo x miricargo x bench