auto await_suspend()

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(); });
      }
    }