For methods like post
, and dispatch
there is one overload taking only a CompletionToken
and another additionally taking an Executor
. As far as I know, the overload without Executor
works as if the overload with the Executor
was called with the CompletionToken
s associated executor. However, what is the effect of passing an Executor
to post
that is not the associated executor of the CompletionToken
? What’s the role of each of the executors? What executor will the CompetionToken
‘s handler be executed on?
I already found out that the assertion in
boost::asio::io_context ioc;
auto ioc_ex = ioc.get_executor();
auto strand_a = boost::asio::make_strand(ioc_ex);
auto strand_b = boost::asio::make_strand(ioc_ex);
boost::asio::post(strand_a, boost::asio::bind_executor(strand_b, [&]() {
assert(strand_a.running_in_this_thread()
&& strand_b.running_in_this_thread());
}));
ioc.run();
succeeds. This surprises me since I assumed that a CompetionToken
‘s handler would only ever be executed in a single Executor
(strand
in this case).
In other answers (e.g. here and here) I’ve read the Executor
passed to post
works as a fallback Executor
for execution of the CompletionToken
‘s handler, in case the latter does not have an associated executor. However, this cannot be its only use, since otherwise, the code above would simply ignore the “fallback” Executor
stand_a
, given the CompletionToken
is explicitly bound to stand_b
.