chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.72k stars 1.19k forks source link

ASIO provides no way to inject into pre-suspend/post-resume awaitable behavior or coroutine_specific_ptr #1493

Open corporategoth opened 2 weeks ago

corporategoth commented 2 weeks ago

I need to replicate something similar to thread-local storage in a project using coroutines.

Unfortunately, the awaitable class does not provide a way to do something prior to suspend in awaitable::await_suspend or post-resume in awaitable::await_resume()

Of course, the ideal would be able to have something like boost::thread::thread_specific_ptr that instead was more coroutine_specific_ptr instead. Such that each awaitable_thread ends up with a different instance - so if I store something in the coroutine_specific_ptr, then what was in it before a co_await is also in it after co_await, but each coroutine stack could have different versions.

But lacking this, if I can inject into the await_suspend and await_resume I can implement a poor-man's version of this, by saving something from my thread_local somewhere in await_suspend, then restoring it on await_resume. I started this by making my own version of awaitable, which then could contain the value I want to store. Unfortunately, this breaks down very quickly, as co_spawn won't take my awaitable, and I also had to create my own version of awaitable_frame (inherited from the asio one) to add an await_transform for my awaitable, and also add coroutine_traits, etc. ie. it just gets messier.

The ideal would be some kind of coroutine_specific_ptr that is part of asio, that could then more or less have it's backing store in the awaitable_thread, so that it could always just address the right one.

corporategoth commented 2 weeks ago

Side note - it would be REALLY nice to have an is_running_in_coroutine() free function. And even a coroutine_identifier function that basically identifies the coroutine thread. Either of these would have made hacking together some kind of coroutine_local_ptr without modifying awaitable_thread (ie. external to asio) easier.