|
Boost Users : |
Subject: Re: [Boost-users] [Asio/Beast] Any non-obvious reasons for no bind_executor_and_allocator?
From: Sorin Fetche (sorin.fetche_at_[hidden])
Date: 2018-12-23 19:58:24
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#L105
>
<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).
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#L227
\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.
>From this perspective it is similar to beast::handler_ptr.
It also uses a bind_allocator utility similar to asio::bind_executor -
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#L84
Best regards,
Sorin
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net