How to customize a coroutine state in boost asio coroutine?

208 views Asked by At

The thing is that I would like to create a global instance which I would be able to use separately by each coroutine to keep there, for instance, the list of named scopes, e.g. for log purposes.

so that when boost::asio::spawn is called a new custom state would be attached to the newly run coroutine.

As a guess, as a workaround it could be done by means of a global std::unordered_map indexed by smth similar to std::this_thread::get_id() but for coroutines. Yet right now I'm not aware of anything like that.

While it would be perfect if it is possible to accomplish this by a custom asio::yield_context. It keeps cancellation_slot, executor, why it cannot keep extra state? I have tryed to dig into the boost sources of yield_context, but I'm rather lost there, that's why I would appreciate some insights on this matter.

1

There are 1 answers

2
sehe On

You need to implement await_transform for a custom type. That allows you to communicate with your promise type. Of course, that's an implementation detail of the library, so you haven't seen it yet.

Here's the await_transform for this_coro::executor_t:

  // This await transformation obtains the associated executor of the thread of
  // execution.
  auto await_transform(this_coro::executor_t) noexcept
  {
    struct result
    {
      awaitable_frame_base* this_;

      bool await_ready() const noexcept
      {
        return true;
      }

      void await_suspend(coroutine_handle<void>) noexcept
      {
      }

      auto await_resume() const noexcept
      {
        return this_->attached_thread_->get_executor();
      }
    };

    return result{this};
  }

You can create your own awaitable type with your own promise-type, which adds you custom state.

There's a non-trivial amount of code here, that will be daunting to write. (It is to me). You should probably dive in with a simpler coroutine tutorial (as "simple" as that can be, which is not very).

I've seen a number of good talks

  • Gor Nishanov's from 2016 which I've personally watched and played along with, so I know it will do a good job https://www.youtube.com/watch?v=8C8NnE1Dg4A
  • A much more recent one by Andreas Fertig from 2022 https://www.youtube.com/watch?v=8sEe-4tig_A (which I haven't seen)
  • The same event had Andreas Weis "Deciphering C++ Coroutines - A Diagrammatic Coroutine Cheat Sheet" (which can also be found elsewhere as "Deciphering C++ Coroutines - A Visual Approach")

There is this blog post series by Raymond Chen which seems very apt. In particular this installment should land you close to the mark: C++ coroutines: Snooping in on the coroutine body