(In reply to Vinnie Falco
I believe you can have one outstanding read and one outstanding write operation pending simultaneously for ssl::stream and tcp::socket.
What about two outstanding read operations or two outstanding write operations? I think they're safe for tcp::socket but not ssl::stream. Moreover, because the documentation has an extra clause in thread safety for ssl::stream which tcp::socket does not have: "The application must also ensure that all asynchronous operations are performed within the same implicit or explicit strand," there should be a difference in the calling requirements for the asynchronous operations in ssl::stream and tcp::socket. Specifically, is there some example code/model that can be used with tcp::socket but not ssl::stream, just because of the extra clause?
Note the careful wording of "implicit or explicit strand." This means: * implicit strand: Only one thread calling io_service::run * explicit strand: Completion handlers are wrapped using io_service::strand::wrap
Apart from handlers called within strands, what other effects does wrapping completion handlers with io_service::strand::wrap have? For example: void handler( const boost::system::error_code& error, std::size_t bytes_transferred ) { ... } void wrapped_handler( const boost::system::error_code& error, std::size_t bytes_transferred ) { strand_.dispatch(boost::bind(&handler, error, bytes_transferred)); } // How does the following differ? ssl_stream.async_read_some(buffer, &wrapped_handler); ssl_stream.async_read_some(buffer, strand_.wrap(&handler)); Since Boost uses argument dependent lookup (ADL) for composed operations [1], I guess it could be similar here. Thanks! [1] https://stackoverflow.com/questions/12794107/why-do-i-need-strand-per-connec...