
On Thu, Dec 20, 2018 at 9:25 AM Sorin Fetche wrote:
On Wed, Dec 19, 2018 at 10:24 PM Vinnie Falco wrote:
Have you considered writing a base class which takes ownership of the user's completion handler and has the necessary hooks?
<snip>
Yes, the base class is a very good idea. It helps reduce the boilerplate in the composed operation and the risk of moving `this` before accessing things in it.
Here's how its usage looks like to implement the composed operation: https://github.com/sorf/cpp-playground/blob/master/source/asio_echo_v2.cpp#L...
<snip>
I still don't like the risk of moving `this` (or `self`) before members in the derived class are used to initiate the next operation (e.g. the echo_buffer).
From this perspective it is similar to beast::handler_ptr. It also uses a bind_allocator utility similar to asio::bind_executor -
With some additional work on the async state helper class, the example composed asynchronous operation becomes pretty compact: https://github.com/sorf/cpp-playground/blob/master/source/asio_echo_v3.cpp#L... \code template <typename StreamSocket, typename CompletionToken> auto async_echo_rw(StreamSocket &socket, CompletionToken &&token) -> /*...*/ { struct state_data { /*...*/}; using state_type = async_state</*...*/, state_data>; state_type state{std::move(completion.completion_handler), socket.get_executor(), socket, /*...*/}; state_data *data = state.get(); data->socket.async_read_some( asio::buffer(data->echo_buffer), state.wrap()([=, state = std::move(state)]( error_code ec, std::size_t bytes) mutable { if (!ec) { asio::async_write(data->socket, /*...*/); } else { state.invoke(ec, bytes); } })); return completion.result.get(); } \endcode The helper class async_state addresses now both the risk of accessing state after it has been moved and the using of the final handler to allocate the internal state. the thing that started this email thread. I haven't tested it in depth yet to confirm that the final handler allocator and executor are properly used in the internal operations, but I would welcome feedback about this async_state helper class. Would it worth trying to turn it into some general purpose utility? Any caveats about asynchronous operations it left unaddressed? https://github.com/sorf/cpp-playground/blob/master/source/asio_echo_v3.cpp#L... Best regards, Sorin