
Hi Peter, --- Peter Dimov <pdimov@mmltd.net> wrote:
Can you explain the "exactly once" principle in more detail, or point me to the documentation that discusses it?
Basically if: - the function used to initiate the operation does not throw; and - the demuxer::run() call is run until there is no work left. the handlers for the operations are guaranteed to be called. See: http://asio.sourceforge.net/boost-asio-proposal-0.3.6/libs/asio/doc/referenc... for example code showing how to ensure that demuxer::run() keeps going until all work is completed even if exceptions are thrown.
boost::asio::socket_acceptor tcp_acceptor(demuxer, boost::asio::ipv4::tcp::endpoint(13));
boost::asio::stream_socket* tcp_socket = new boost::asio::stream_socket(demuxer);
tcp_acceptor.async_accept(*tcp_socket, boost::bind(handle_tcp_accept, &tcp_acceptor, tcp_socket, boost::asio::placeholders::error));
For example, what happens here if async_accept fails, perhaps because of insufficient memory? Does it throw bad_alloc?
It could.
Is the handler executed?
No (according to above rules). This particular code doesn't seem to be exception safe as it stands :o) It should be more like: std::auto_ptr<boost::asio::stream_socket> tcp_socket( new boost::asio::stream_socket(demuxer)); tcp_acceptor.async_accept(*tcp_socket, boost::bind(handle_tcp_accept, &tcp_acceptor, tcp_socket, boost::asio::placeholders::error)); tcp_socket.release(); However, this is probably all too complicated for a tutorial. I'm now leaning towards just going with the shared_from_this() style for the tutorial (as used in the HTTP server example), with an appropriate link into the shared_ptr docs explaining it. If a developer is sufficiently motivated to want to eliminate the costs of using shared_ptr, I'll point them to other examples that showcase alternative styles. Cheers, Chris