auto await_suspend()

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