3

In a coroutine function, we can add auto ex = co_await asio::this_coro::executor; to get the executor of this coroutine. But when I want to learn the definition of it, I found this:

/// Awaitable type that returns the executor of the current coroutine.
struct executor_t
{
  ASIO_CONSTEXPR executor_t()// ASIO_CONSTEXPR is defined constexpr
  {
  }
};

/// Awaitable object that returns the executor of the current coroutine.
#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
constexpr executor_t executor;
#elif defined(ASIO_MSVC)
__declspec(selectany) executor_t executor;
#endif

Why does executor awiatable?

1 Answers1

2

As explained here, when co_await is reached, the expression following the co_await is converted to an awaitable:

otherwise, if the current coroutine's Promise type has the member function await_transform, then the awaitable is promise.await_transform(expr)

Looking at the coro_promise type defined in asio/include/asio/experimental/coro.hpp we can indeed find an overload of this method taking this_coro::executor_t as parameter:

  auto await_transform(this_coro::executor_t) const
  {
    struct exec_helper
    {
      const executor_type& value;

      constexpr static bool await_ready() noexcept { return true; }

      constexpr static void await_suspend(coroutine_handle<>) noexcept {}

      executor_type await_resume() const noexcept { return value; }
    };

    return exec_helper{executor_};
  }

This won't suspend the coroutine since await_ready() of exec_helper always returns true. Instead it will immediately call await_resume() which, as you can see above, returns the executor stored in the current promise.

So the only purpose of the this_coro::executor_t is for overload resolution. There is another overload for this_coro::cancellation_state_t which has a similar empty definition that serves the same purpose.

The global variable constexpr executor_t executor; is there so that you can pass this_coro::executor instead of this_coro::executor_t{} to the co_await operator inside your coroutine.

Mikhail Vasilyev
  • 503
  • 4
  • 11