
On Mon, Jan 31, 2011 at 7:30 PM, Timothy Liang <timothy003@msn.com> wrote:
<<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?
It doesn't do that. It's smart enough to see that it's in a given strand which may be blocked so it moves on to the next available scheduled handler. I do it all the time and I haven't seen it be the bottleneck for anything I've developed with Boost.Asio even in the early days and leading up to especially now. Give it a shot and then measure to identify which part of the solution is causing you problems. HTH -- Dean Michael Berris about.me/deanberris