0

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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
unegare
  • 2,197
  • 1
  • 11
  • 25

1 Answers1

1

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

sehe
  • 374,641
  • 47
  • 450
  • 633
  • 1
    I completely misread the premise here. I assumed c++20 coroutines, primed by [this comment](https://stackoverflow.com/questions/75132146/how-to-use-boostlog-named-scope-with-boostasioyield-context#comment132591175_75133312). Will be back tomorrow or monday to revisit with `spawn` – sehe Jan 22 '23 at 02:45
  • you have written an excellent list of things to pore over in case of `C++20` and I appreciate to keep it as well, although this post was focused on `C++17`, as `C++20` is widely considered as not ready for product yet by most firms. – unegare Jan 22 '23 at 17:22