Hm, on second thought, maybe you DO need to hold the lock during the async_read (to prevent the other thread from closing the socket).  I'm trying to decide whether there is an improvement in concurrency by using the shared mutex.  Can there be multiple threads in these handler functions, or are they all called exclusively by the io_service thread?  Are we allowing the client to choose how to use io_service, or can we guarantee a single io_service thread?