in demo_example/asio/asio/experimental/impl/coro.hpp [899:975]
auto await_suspend(
detail::coroutine_handle<detail::coro_promise<Y, R, E>> h)
-> detail::coroutine_handle<>
{
auto& hp = h.promise();
if constexpr (!detail::coro_promise<Y, R, E>::is_noexcept)
{
if ((hp.cancel->state.cancelled() != cancellation_type::none)
&& hp.cancel->throw_if_cancelled_)
{
asio::detail::throw_error(
asio::error::operation_aborted, "coro-cancelled");
}
}
if (hp.get_executor() == coro_.get_executor())
{
coro_.coro_->awaited_from = h;
coro_.coro_->cancel = hp.cancel;
coro_.coro_->reset_error();
return coro_.coro_->get_handle();
}
else
{
coro_.coro_->awaited_from = detail::dispatch_coroutine(
asio::prefer(hp.get_executor(),
execution::outstanding_work.tracked),
[h]() mutable
{
h.resume();
});
coro_.coro_->reset_error();
struct cancel_handler
{
std::shared_ptr<std::pair<cancellation_signal,
detail::coro_cancellation_source>> st = std::make_shared<
std::pair<cancellation_signal, detail::coro_cancellation_source>>();
cancel_handler(E e, coro& coro) : e(e), coro_(coro.coro_)
{
st->second.state = cancellation_state(
st->second.slot = st->first.slot());
}
E e;
typename coro::promise_type* coro_;
void operator()(cancellation_type ct)
{
asio::dispatch(e,
[ct, st = st]() mutable
{
auto & [sig, state] = *st;
sig.emit(ct);
});
}
};
if (hp.cancel->state.slot().is_connected())
{
hp.cancel->state.slot().template emplace<cancel_handler>(
coro_.get_executor(), coro_);
}
auto hh = detail::coroutine_handle<
detail::coro_promise<Yield, Return, Executor>>::from_promise(
*coro_.coro_);
return detail::dispatch_coroutine(
coro_.coro_->get_executor(),
[hh]() mutable { hh.resume(); });
}
}