Document non-structured-concurrenty caveats in coro::merge(), fix one of them
Summary: Part of the added comment about `folly::coro::merge()`: // Currently this doesn't fully do structured concurrency. Care is needed to // avoid use-after-free when the stream is terminated early, as some cancelled // input streams may be left running in background. // The rule is: if output generator's next() returned an empty value // (end of stream), it's guaranteed that 'sources' and all input coroutines are // completed and destroyed, no use-after-free danger. In all other cases // (next() returned an exception or the output generator was destroyed early), // the input generators may be left running in background (cancelled and // detached). This diff adds a long comment about this and a couple other quirks (or what I would consider quirks). It also fixes one of the quirks: the merged stream may return end-of-stream when 'source' coroutine frame is not destroyed yet. So if the 'source' coroutine e.g. has a `SCOPE_EXIT` that references some state owned by the caller of `merge()`, it may in principle use-after-free. This diff destroys 'source' coroutine frame just before returning end-of-stream rather than just after. This way `merge()` is at least possible to use in "strucutured concurrency" style, as long as you avoid exceptions and always drain the merged generator before destroying it. It would be easy to do the same for the exception case (just wait for the `makeConsumerTask()` coroutine to complete before calling `throw_exception()`). This would make `merge()` as close to structured concurrency as is possible with `folly::AsyncGenerator` (which can always be synchronously destroyed, leaving no choice but to detach child coroutines; but as long as the user doesn't do that, it should be fine). But I'm hesitant to do it because some existing call sites might rely on current behavior. I'll leave this to the team that actually owns this code. Same for the two cancellation quirks listed in the added comment. Reviewed By: iahs Differential Revision: D33557074 fbshipit-source-id: cf7aaee8ec78e21c370d1f7faff3b4bad1327c95
Showing
Please register or sign in to comment