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
fix: avoid leaking CheckedContinuations by removing possible Channel actor reentrancy
In the Channel.fulfill and Channel.fail methods, the line `await state.removeAllWaiters()` allows for actor reentrance. This means that after resuming all the CheckedContinuations (waiters), but before removing them, another waiter could be added to the array. Then once the `state.removeAllWaiters` resumes execution, any CheckedContinuations would be removed without having been resumed. This leads to leaking CheckedContinuations.
This was observed in my application, where I would get a logger message
SWIFT TASK CONTINUATION MISUSE: value leaked its continuation without resuming it. This may cause tasks waiting on it to remain suspended forever.
which originates from Swift here: https://github.com/swiftlang/swift/blob/b06eed151c8aa2bc2f4e081b0bb7b5e5c65f3bba/stdlib/public/Concurrency/CheckedContinuation.swift#L82
I verified that Channel.value was the culprit by renaming it and observing the changed name in the CONTINUATION MISUSE message.
This change set removes the possibility of actor reentrancy and leaking CheckedContinuations. By inlining the State data members in Channel and deleting the State actor completely, we remove all await calls inside Channel.fulfill and Channel.fail.
0 commit comments