On Wed, Dec 19, 2018 at 10:08 PM Richard Hodges via Boost
Adding some lessons learned over the years to Vinnie's answer, because it's not immediately obvious from the ASIO documentation...
Wow... yeah. I have been saying that the "problem" with Asio / Networking TS is the lack of good documentation and tutorials. And this is not meant as a slight against the Asio author - it is a pretty hefty library with big implications and it would be unfair to presume that the burden of all present and future learning materials should fall on him. There are folks who think that networking is "too complicated" but again I feel this would be addressed by having good literature. Your post was great, it touched on a lot of good guidelines. We need this sort of thing in a readily accessible reference format, then I think networking will be seen in an even more favorable light.
If you're using strands then all access to your object from outside should be via an async function which takes a closure and posts an implementation of itself to the current object's strand. This ensures that everything runs in the correct thread (which you can assert with strand::running_in_this_thread() in your handler functions).
For member functions of application-level classes owning I/O objects, where those member functions can be called from foreign threads I use this idiom: void session::do_thing(Arg arg) { if(! strand_.running_in_this_thread()) return boost::asio::post( boost::asio::bind_executor(strand_), std::bind(&session::do_thing, shared_from_this(), arg)); // at this point, the thread of execution is on the strand async_do_something(socket_, arg, ...); } This way, do_thing can be called from anywhere. Regards