The connection class inherits from std::enable_shared_from_this<connection>, and is then passed in a shared_ptr (the captured 'self') to the handler function registered with the async_read_some in connection::do_read(). Is this approach, and the related design decsision that the server creates a shared_ptr to a new connection in its server::do_accept() function, taken simply in order to ensure that the connection object is kept alive for as long as any asynchronous read/write operation requires it?
So is it implying that if the connection was NOT kept alive by a shared_ptr (i.e., was instead created by the server and stored by value in a std container) something bad could and likely would happen at some point, most likely due to the handler being called on an object that no longer exists? This might be when a boost::asio::error::operation_aborted is reported by the handler, when a current async operation is cancelled during the server/connection_manager shutdown process as a result of closing the socket, after the connection object value has been removed from the container, for example?
Is this shared_ptr approach the idiomatic or even the only way to manage lifetimes in ASIO async calls? It just looks a bit ugly to me, bloats the code a bit and I was wondering if there is any other way to do it without the intrusion of shared_ptrs into the mix?
Re: Boost ASIO HTTP Server example design question
On Mon, Aug 12, 2019 at 8:57 AM TomJordan via Boost-users
<[hidden email]> wrote:
> Is this shared_ptr approach the idiomatic or even the only way to
> manage lifetimes in ASIO async calls?
It is not the only way, but by far the simplest and safest - once you
achieve a grasp of how asynchrony works and how to manage lifetimes.
> It just looks a bit ugly to me, bloats the code a bit and I was wondering if there is
> any other way to do it without the intrusion of shared_ptrs into the mix?
My advice: get over it. There is nothing wrong with `shared_ptr` and
it is the most natural way to manage objects whose lifetime is not
deterministic. For example if you perform an asynchronous read and an
asynchronous write with the same object, there's no way to know which
operation will finish last. Shared-ownership (i.e. `shared_ptr`) is
the right tool here.
This video and the example code that is used in the video should give
you a running start on learning asio and asynchronous programming. It
explains how to use shared_ptr in detail to manage lifetimes.