Hi everyone,
Back in September Dmitry offered the following alternative to the to the
asynchronous TCP echo server example (
https://www.boost.org/doc/libs/1_77_0/doc/html/boost_asio/example/cpp11/echo...)
that uses a unique_ptr instead of shared_ptr for managing the lifetime of
the session (the socket and the buffer):
wt., 21 wrz 2021 o 17:22 Дмитрий Архипов via Boost
I haven't tested it, but this should probably work:
class session { public: session(tcp::socket socket) : session(std::make_unique
(std::move(socket))) {} void start() { do_read(); }
private: session(std::unique_ptr
impl) : impl_(std::move(impl)) {} void do_read() { auto& impl = *impl_; impl.socket.async_read_some( boost::asio::buffer(impl.data, max_length), [impl = std::move(impl_)](boost::system::error_code ec, std::size_t length) mutable { if (ec) { return; } session(std::move(impl)).do_write(length); }); }
void do_write(std::size_t length) { ... }
auto constexpr max_length = 1024; struct session_impl { session_impl(tcp::socket socket) : socket_(std::move(socket)) {} tcp::socket socket_; char data_[max_length]; }; };
...
session(std::move(socket)).start();
The idea here is that the last completion handler to be installed is responsible for calling the destructor. But this can only work under the assumption that the ASIO framework guarantees that the completion handler is destroyed after all the preceding operations have finished. Otherwise we can envision the situation where the destructor in the handler is called but the previous operation is still trying to access the socket. Under normal circumstances, it should be quite obvious that the previous operation is finished before the handler is invoked and destroyed. But it is not that obvious when we add the operation cancellation into the picture. I could imagine an implementation where an operation receives a cancellation request, it already knows that it will not be calling the completion handler, so it destroys the handler, and then does its own cleanup. So, my question is: does ASIO give a guarantee that it destroys the completion handler after the preceding operations have finished? Regards, &rzej;