Reputation: 130
Since latest versions of boost, asio comes up with its new executors and provides with asio::strand<Executor>
. So it is now perfectly possible to use asio::strand<asio::io_context::executor_type>
instead of io_context::strand
. But they cannot be used interchangeably.
Upvotes: 5
Views: 4313
Reputation: 393769
io_context::strand
is "legacy". I assumed it exists for interface compatibility with code that still uses boost::asio::io_service
(also deprecated).
As the comments reflect I've since found out that
io_context::strand
is not actually deprecated, although I see no reason why this is the case, and close reading of the implementation leaves me with the conclusion that
asio::strand<Executor>
is strictly bettermixing both strand services is not the best idea. In fact both services are documented with the same tag line:
// Default service implementation for a strand.
I can't help feeling there should be only one default :)
Modern strands don't reference an execution context, but wrap an executor.
While being technically different, it is conceptually the same.
The usage is the same for posting tasks:
post(s, task); // where s is either legacy or modern
defer(s, task);
dispatch(s, task);
In fact you may have tasks with an associated executor, see:
You can no longer use the legacy strand to construct IO service objects (like tcp::socket or steady_timer). That's because the legacy strand cannot be type-erased into any_io_executor
:
using tcp = boost::asio::ip::tcp;
boost::asio::io_context ioc;
auto modern = make_strand(ioc.get_executor());
tcp::socket sock(modern);
boost::asio::io_context::strand legacy(ioc);
tcp::socket sock(legacy); // COMPILE ERROR
If you really want you can force it by not using any_io_executor
:
boost::asio::basic_stream_socket<tcp, decltype(legacy)> sock(legacy);
sock.connect({{}, 8989});
Upvotes: 4