C++ Logo

std-proposals

Advanced search

Re: async coroutines vs. lambdas

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Thu, 14 May 2020 13:33:43 +0200
czw., 14 maj 2020 o 13:14 Ville Voutilainen via Std-Proposals
<std-proposals_at_[hidden]> napisaƂ(a):
>
> On Thu, 14 May 2020 at 13:58, Avi Kivity via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> > Coroutines capture parameters passed by value and copy them to the
> > coroutine frame (all quotes from cppreference):
> >
> >
> > > When a coroutine begins execution, it performs the following:
> > >
> > > allocates the coroutine state object using operator new (see below)
> > > copies all function parameters to the coroutine state: by-value
> > parameters are moved or copied, by-reference parameters remain
> > references (and so may become dangling if the coroutine is resumed after
> > the lifetime of referred object ends)
> > >
> >
> > This allows a coroutine's parameters to outlive the point it is launched at:
> >
> >
> > void foo() {
> >
> > call_some_coroutine(a_temporary_value());
> >
> > }
> >
> >
> > Normally, a_temporary_value() would e destroyed at the end of the
> > expression, which can be before the coroutine completes.
> >
> >
> > With a lambda coroutine, we have a problem. This is because lambdas are
> > captured by reference:
>
> Says what?
>
> > > If the coroutine is a non-static member function, such as task<void>
> > my_class::method1(int x) const;, its Promise type is
> > std::coroutine_traits<task<void>, const my_class&, int>::promise_type
> >
> >
> > For a lambda, the non-static member function is
> > synthetic_lambda_type::operator() const, and so the lambda would be
> > captured as const synthetic_lambda_type&. Consider this call:
>
> No. The lambda is the coroutine, not its operator().

You mean that lambdas have special wording that make them behave
different to local objects with member function that return task?

For me this is more case of data race, handle to coroutine should be
destroyed before lambda object is destroyed too.
This mean `task<>` should cancel request or block until it is
finished, then we do not have any problems there.

Received on 2020-05-14 06:36:56