From: Christopher Kohlhoff (chris_at_[hidden])
Date: 2006-08-17 20:59:32
Rod Morison <rod_at_[hidden]> wrote:
> I'm trying to think through how to perform a clean shutdown in
> this example. There could be a number of pending
> async_write()'s, each with their own socket and uncalled
> handler. There is probably also a socket waiting on the
> async_accept() with an an uncalled handler.
> - With the work pending, io_service will need to call it's
> interrupt() function (from another thread) to stop processing,
Actually, there are two basic approaches to clean shutdown.
Interrupting the io_service::run() is one. The other is to
cancel all outstanding work and let io_service::run() exit
because it runs out of work.
The first involves forcing io_service::run() to exit by calling
io_service::interrupt(). As you say, this means that there will
still be work pending. However, the io_service destructor causes
all copies of user-defined handlers to be destroyed. If you
follow the daytime server example of using shared_ptrs to manage
your object lifetimes, these objects will all be cleaned up
The second approach is to cancel the asynchronous operations by
explicitly closing all the sockets and acceptor. The operations
will all complete with the operation_aborted error, and provided
you don't start any new async operations the io_service::run()
function will exit due to lack of work. See the HTTP server
program for an example of this approach.
> - I can close the tcp::acceptor in tcp_server, but what about
> the socket that's listening on it?
If you're referring to the peer socket that is being "accepted",
you don't need to do anything with it. The asynchronous accept
operation is "owned" by the acceptor, so closing the acceptor is
sufficient to abort the operation. No resource is assigned to
the peer socket unless the accept is successful.