c++ - co_await appears to be suboptimal? -


i have async function

void async_foo(a& a, b& b, c&c, function<void(x&, y&)> callback); 

i want use in stackless coroutine write

auto coro_foo(a& a, b& b, c& c, x& x) /* -> y */ {   struct awaitable {     bool await_ready() const noexcept { return false; }     bool await_suspend(coroutine_handle<> h) {       async_foo(*a_, *b_, *c_, [this, h](x& x, y& y){         *x_ = std::move(x);         y_ = std::move(y);         h.resume();       });     }     y await_resume() {       return std::move(y);     }     a* a_; b* b_; c* c_; x* x_; y y_;   };   return awaitable{&a, &b, &c, &x}; } 

then can use this:

y y = co_await coro_foo(a, b, c, x); 

and compiler rewrite this:

  auto e = coro_foo(a, b, c, x);   if (!e.await_ready()) {     <suspend>     if (e.await_suspend(h)) return; resume-point:     <resume>   }   y y = e.await_resume(); 

with this, coroutine keep a_, b_, , c_ when it's suspended, when have keep them until coroutine_handle in await_suspend(h).
(btw i'm not sure if can keep references arguments here.)

it more efficient if wrapper function directly coroutine_handle argument.

it implicit argument:

promise f(coroutine_handle<> h); co_await f(); 

or special keyword-argument:

promise f(coroutine_handle<> h); f(co_await); 

am missing here? (other overhead not big.)

the "coroutine" system defined coroutine ts designed handle asynchronous functions which:

  1. return future-like object (an object represents delayed return value).
  2. the future-like object has ability associated continuation function.

async_foo doesn't fulfill these requirements. doesn't return future-like object; "returns" value via continuation function. , continuation passed parameter, rather being object's return type.

by time co_await happens @ all, potentially asynchronous process generated future expected have started. or @ least, co_await machinery makes possible have started.

your proposed version loses out on await_ready feature, allows co_await handle potentially-asynchronous processes. between time future generated , await_ready called, process may have finished. if has, there no need schedule resumption of coroutine. should therefore happen right here, on thread.

if minor stack inefficiency bothers you, have things way coroutine ts wants to.

the general way handle coro_foo directly execute async_foo , return future-like object .then-like mechanism. problem async_foo doesn't have .then-like mechanism, have create one.

that means coro_foo must pass async_foo functor stores coroutine_handle<>, 1 can updated future's continuation mechanism. of course, you'll need synchronization primitives. if handle has been initialized time functor has been executed, functor calls it, resuming coroutine. if functor completes without resuming coroutine, functor set variable let await machinery know value ready.

since handle , variable shared between await machinery , functor, you'll need ensure synchronization between two. that's complex thing, it's whatever .then-style machinery requires.

or live minor inefficiency.


Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -