
<<In the case of composed asynchronous operations, such as async_read() or async_read_until(), if a completion handler goes through a strand, then all intermediate handlers should also go through the same strand. This is needed to ensure thread safe access for any objects that are shared between the caller and the composed operation (in the case of async_read() it's the socket, which the caller can close() to cancel the operation). This is done by having hook functions for all intermediate handlers which forward the calls to the customisable hook associated with the final handler>> http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/overview/core/stran...
Ah! It also says, "The io_service::strand::wrap() function creates a new completion handler that defines asio_handler_invoke so that the function object is executed through the strand." And the composed operations have a hook on their intermediate handlers that call asio_handler_invoke with the completion handler's context. So I simply need to pass the wrapped handler object directly to the composed operations as the completion handler. Cool. Now I'm beginning to wonder if this will work with my design. I want my program to run handlers as concurrently as possible. I'm currently using a single io_service and setting up a thread pool like the HTTP Server 3 example. Since the io_service doesn't know if a handler would be blocked by a strand, it could needlessly assign an about-to-be-blocked handler to a free thread. How do I fix that?