Skip to content

fix: clone wakers outside state locks - #245

Merged
tisonkun merged 4 commits into
apache:mainfrom
tisonkun:codex/fix-waitset-waker-clone
Aug 30, 2026
Merged

fix: clone wakers outside state locks#245
tisonkun merged 4 commits into
apache:mainfrom
tisonkun:codex/fix-waitset-waker-clone

Conversation

@tisonkun

@tisonkun tisonkun commented Aug 30, 2026

Copy link
Copy Markdown
Member

Summary

  • make WaitSet accept an owned Waker so it cannot clone user-provided wakers while a primitive state lock is held
  • reduce the internal lifecycle API to will_wake, register, unregister, and drain, and consistently name each future's slot identity a WakerToken
  • simplify Completion, Countdown-backed Latch and WaitGroup, Barrier, Watch, and Broadcast registration paths while keeping unused, replaced, removed, and drained wakers outside their locks
  • add deterministic reentrant callback regressions and include them in the targeted Miri workflow

Design Notes

A RawWaker clone, drop, or wake callback is arbitrary user code and may reenter the primitive using it. WaitSet therefore only moves already owned wakers under its owner's lock; callers clone before locking and process every waker returned by register, unregister, or drain after unlocking.

WakerToken identifies one cancellable waiter slot without implying ownership of the waker itself. Its epoch invalidates tokens retained by futures after a non-empty drain, which prevents them from aliasing slots reused by later waiters. epoch is 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 main showed no consistent regression beyond run-to-run noise.

Tests

  • cargo x check
  • cargo x test
  • cargo x lint
  • MIRIFLAGS='-Zmiri-strict-provenance -Zmiri-symbolic-alignment-check -Zmiri-many-seeds=0..4' cargo x miri
  • cargo x bench

@tisonkun
tisonkun merged commit da53366 into apache:main Aug 30, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant