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
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