The documentation of boost::asio::this_coro::executor
states that it is an
Awaitable object that returns the executor of the current coroutine.
To me this seems somewhat vague as soon as multiple Executors
come into play; I assumed that co_await
ing it would provide the Executor
the coroutine is currently executed on, i.e. I expected the assertion in this snipped to succeed:
boost::asio::io_context ioc;
auto io_ex = ioc.get_executor();
boost::asio::co_spawn(io_ex,
[&]() -> boost::asio::awaitable<void> {
auto switch_strand = boost::asio::make_strand(io_ex);
co_await boost::asio::post(switch_strand, boost::asio::use_awaitable);
assert(switch_strand == co_await boost::asio::this_coro::executor);
},
boost::asio::detached);
ioc.run();
However it turns out that, even after the post
to switch_strand
, io_ex == co_await boost::asio::this_coro::executor
. Why does that happen? Will co_await boost::asio::this_coro::executor
always produce the Executor
the coroutine was originally co_spawn
ed on, regardless of whether I switch to any other Executor
within the coroutine? Does the call to post
with switch_strand
even "switch to any other Executor
within the coroutine"?
The executor is a property of the coroutine. This why you can query the awaitable's promise type using the transformable (this_coro::executor
). There might even be a conscious design choice that opted for
auto ex = co_await this_coro::executor; // this syntax
over
auto ex = co_await this_coro::executor(); // instead of this syntax
as opposed to other interactive transformation.
Why does that happen?
That's just how it was designed. In most senses, coroutines are self-modifying continuations. Continuations are handlers. Handlers can have associated executors. When you co_spawn(ex, foo, ...)
you ask all these continuations to bind to ex
.
See also code comments
Will co_await boost::asio::this_coro::executor always produce the Executor the coroutine was originally co_spawned on
Yes. See also transform in code
regardless of whether I switch to any other Executor within the coroutine? Does the call to post with switch_strand even "switch to any other Executor within the coroutine"?
Yes and no:
co_await post(bind_executor(x, deferred));
will cause the coroutine to resume on x.