Date: Sun, 7 Jul 2024 19:47:06 -0400
On Mon, Jun 24, 2024 at 11:53 AM Артём Колпаков via Std-Discussion <
std-discussion_at_[hidden]> wrote:
> Good day. I'm learning coroutines and I don't see any clarification in the
> standard about a few things.
>
> First, can a coroutine be resumed inside an await_suspend call? I mean the
> following patterns
>
> void await_suspend(auto self) {
> self.resume();
> }
>
> bool await_suspend(auto self) {
> self.resume();
> return false; // UB here?
> }
>
> auto await_suspend(auto self) {
> auto h2 = some_handle_;
> self.resume();
> return h2;
> }
>
> These calls behave differently. If false is returned, the coroutine is
> resumed twice from the same point, which (maybe) looks like an optimization
> in the implementations. This happens in both gcc and clang (
> https://godbolt.org/z/KM63dooae)
>
> The second thing I'd like to find out is, is it possible to return the
> handle of the coroutine itself to resume it directly? And can it be
> combined with the above?
>
> auto await_suspend(auto self) {
> // self.resume();
> return self;
> }
>
I think the first case where you call `resume()` directly, and then return
`void`, is fine because there's no second resumption. The same goes for the
last case.
The only precondition for `std::coroutine_handle<P>::resume()` is that the
coroutine it refers to is suspended and not at its final suspend point (
[coroutine.handle.resumption]/2
<http://eel.is/c++draft/coroutine.handle.resumption#2>). When
`await_suspend` is entered, the coroutine has already been suspended (
[expr.await]/5.1 <http://eel.is/c++draft/expr.await#5.1>), so resuming the
enclosing coroutine is permitted.
About the second and third cases where there's an implicit resumption upon
return from `await_suspend`, it does seem odd to me that the result is not
the same as that of explicitly calling `resume()` twice. Like you say,
maybe this is an optimization. And maybe the compilers do this optimization
because they believe that it should be UB when you do this. I suggest
filing bugs against clang and gcc and then you can see how they respond.
>
> Thank you for your attention.
> Artyom Kolpakov
>
> Translated with DeepL.com (free version)
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
std-discussion_at_[hidden]> wrote:
> Good day. I'm learning coroutines and I don't see any clarification in the
> standard about a few things.
>
> First, can a coroutine be resumed inside an await_suspend call? I mean the
> following patterns
>
> void await_suspend(auto self) {
> self.resume();
> }
>
> bool await_suspend(auto self) {
> self.resume();
> return false; // UB here?
> }
>
> auto await_suspend(auto self) {
> auto h2 = some_handle_;
> self.resume();
> return h2;
> }
>
> These calls behave differently. If false is returned, the coroutine is
> resumed twice from the same point, which (maybe) looks like an optimization
> in the implementations. This happens in both gcc and clang (
> https://godbolt.org/z/KM63dooae)
>
> The second thing I'd like to find out is, is it possible to return the
> handle of the coroutine itself to resume it directly? And can it be
> combined with the above?
>
> auto await_suspend(auto self) {
> // self.resume();
> return self;
> }
>
I think the first case where you call `resume()` directly, and then return
`void`, is fine because there's no second resumption. The same goes for the
last case.
The only precondition for `std::coroutine_handle<P>::resume()` is that the
coroutine it refers to is suspended and not at its final suspend point (
[coroutine.handle.resumption]/2
<http://eel.is/c++draft/coroutine.handle.resumption#2>). When
`await_suspend` is entered, the coroutine has already been suspended (
[expr.await]/5.1 <http://eel.is/c++draft/expr.await#5.1>), so resuming the
enclosing coroutine is permitted.
About the second and third cases where there's an implicit resumption upon
return from `await_suspend`, it does seem odd to me that the result is not
the same as that of explicitly calling `resume()` twice. Like you say,
maybe this is an optimization. And maybe the compilers do this optimization
because they believe that it should be UB when you do this. I suggest
filing bugs against clang and gcc and then you can see how they respond.
>
> Thank you for your attention.
> Artyom Kolpakov
>
> Translated with DeepL.com (free version)
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
-- *Brian Bi*
Received on 2024-07-07 23:47:21