Get io_context reference from a socket in Boost 1.73+ Asio

Viewed 3870

How can I get boost::asio::io_context reference from a socket? Previously there were socket::get_io_service and then socket::get_io_context member functions, however now they both are deprecated. I've found the only way to do this in Boost 1.73+:

boost::asio::ip::tcp::socket socket(...);
// ...
boost::asio::io_context& io_context = static_cast<boost::asio::io_context&>(socket.get_executor().context());

This works, however looks ugly and dangerous. Is there a better way?

1 Answers

You would probably want to get the executor, which might be something other than the io_context.

There's a get_executor() call to do it directly:

boost::asio::io_context io;
boost::asio::ip::tcp::socket s(io);
auto ex = s.get_executor();

The executor will allow you to do most things you were probably using the io_context for.

UPDATE

To the comment, I do NOT recommend relying on the exact target of the executor you get passed in via any service object, but you can force your hand if you really don't want to update your design right now:

Live On Coliru

#include <boost/asio.hpp>
int main() {
    boost::asio::io_context io;
    boost::asio::ip::tcp::socket s(io);

    auto ex = s.get_executor();

    auto* c = ex.target<boost::asio::io_context>();
    boost::asio::ip::tcp::socket more_sockets(*c);

    assert(c == &io);
}

When compositing async operations, you can derive an executor from a handler using boost::asio::get_associated_executor()

Related