C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Mark co_routine with [[co_clean]] for premature destruction of generator

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Fri, 19 May 2023 15:40:34 -0500
On Fri, 19 May 2023 at 13:04, Frederick Virchanza Gotham via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
> Let's say I write a generator coroutine that gives the letters of the
> alphabet up until z, and then co_return's.
>
> So let's say we invoke the routine and get a generator object from it:
>
> auto gen = GetAlphabet();
>
> Next let's say that we invoke the generator 5 times giving us a,b,c,d,e.
> But then, before the coroutine has co_return'ed, we destroy the generator
> object. I haven't been able to find out from websearching what's supposed
> to happen if you prematurely destroy the generator object. Is it undefined
> behaviour?
>

If you destroy the coroutine while it is suspended, all automatic objects
that are in scope at the suspension point are destroyed in the expected
order.

If you destroy the coroutine while it is *not* suspended, the behavior is
undefined. http://eel.is/c++draft/dcl.fct.def.coroutine#11.sentence-4

Anyway I propose that we can mark a coroutine with [[co_clean]], and that
> it will have the following effect:
> If you prematurely destroy the generator object, it will behave as though
> you invoked the generator again but immediately encountered a 'co_return',
> thus all the appropriate destructors will be called for local objects
> inside the coroutine.
>
> This feature would be really useful for me in a networking program I'm
> currently writing. I have a thread that has a loop iterating through 6
> generator objects calling them all in sequence. But when the thread's
> stop_token is triggered, it would be convenient to just return from the
> thread without having to gracefully end the coroutines.
>
> As far as I'm aware, and I'm open to correction here, at the time of
> writing, with C++23, to get this kind of behaviour, you need to follow
> every co_yield with a co_return, something like:
>
> for ( char c = 'a'; c <= 'z'; ++c )
> {
> co_yield c;
> if ( global_boolean_to_stop ) co_return;
> }
>
> And so then in the thread that invokes the coroutines, when the stop_token
> is triggered, you need to set 'global_boolean_to_stop' and invoke the
> generator one more time. It would be easier instead just to mark it
> [[co_clean]].
>
> But of course this new feature proposal of mine won't be viable if the
> desired behaviour is already what happens when you prematurely destroy a
> generator.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2023-05-19 20:40:48