in demo_example/asio/asio/experimental/impl/coro.hpp [163:235]
auto await_suspend(coroutine_handle<coro_promise<Y, R, E>> h)
-> coroutine_handle<>
{
auto& hp = h.promise();
if constexpr (!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_->reset_error();
coro.coro_->input_ = std::move(value);
coro.coro_->cancel = hp.cancel;
return coro.coro_->get_handle();
}
else
{
coro.coro_->awaited_from =
dispatch_coroutine(
asio::prefer(hp.get_executor(),
execution::outstanding_work.tracked),
[h]() mutable { h.resume(); });
coro.coro_->reset_error();
coro.coro_->input_ = std::move(value);
struct cancel_handler
{
using src = std::pair<cancellation_signal,
detail::coro_cancellation_source>;
std::shared_ptr<src> st = std::make_shared<src>();
cancel_handler(E e, coro_t& coro) : e(e), coro_(coro.coro_)
{
st->second.state =
cancellation_state(st->second.slot = st->first.slot());
}
E e;
typename coro_t::promise_type* coro_;
void operator()(cancellation_type ct)
{
asio::dispatch(e, [ct, p = coro_, 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<
typename coro_t::promise_type>::from_promise(*coro.coro_);
return dispatch_coroutine(
coro.coro_->get_executor(), [hh]() mutable { hh.resume(); });
}
}