You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Deferred completion with an interrupt cause skips suspended waiters (waiter never resumes) #7365
4.0.0-beta.107 (code unchanged at current main; affects at least 4.0.0-beta.107 through current)
What steps can reproduce the bug?
Complete a Deferred that has two or more suspended waiters with an effect whose cause contains an interrupt, e.g. Deferred.done(deferred, Exit.failCause(Cause.interrupt())).
Without the timeout, any fiber joining the second waiter hangs indefinitely.
Additional information
Mechanism: doneUnsafe iterates self.resumes live while resuming waiters. Resuming a suspended waiter with an interrupt cause kills that waiter fiber synchronously inside resume(effect), and the dying waiter's Deferred.await cleanup splices its entry out of the shared resumes array mid-iteration. The next waiter shifts down into the just-visited index, the loop index moves past it, and it is never resumed.
The #7193 guard made the cleanup safe after completion (resumes === undefined), but preserved the splice when cleanup fires during the completion loop, which is exactly this window.
All completion paths (done, complete, completeWith, fail, die, interrupt, into, and direct doneUnsafe callers such as PubSub and ScopedCache) funnel through the same loop.
Activity