Reizo
Reizo

Reputation: 1437

What executor does co_await boost::asio::this_coro::executor produce?

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_awaiting 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_spawned 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"?

Upvotes: 1

Views: 355

Answers (1)

sehe
sehe

Reputation: 393674

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:

  • Yes co_await post(bind_executor(x, deferred)); will cause the coroutine to resume on x.
  • No, it doesn't alter the coroutine's internal attached_thread_ properties

Upvotes: 2

Related Questions