asio::async_write(m_socket, asio::buffer(buf, bytes),
                custom_alloc(m_strand.wrap(custom_alloc(_OnSend))));
Does this code guarantee that all asynchronous operation handlers(calls to async_write_some) inside async_write are called through strand? (or it's just for my_handler?)
With the following code:
asio::async_write(stream, ..., custom_alloc(m_strand.wrap(...)));
For this composed operation, all calls to stream.async_write_some() will be invoked within m_strand if all of the following conditions are true:
The initiating async_write(...) call is running within m_strand():
assert(m_strand.running_in_this_thread());
asio::async_write(stream, ..., custom_alloc(m_strand.wrap(...)));
The return type from custom_alloc is either:
the exact type returned from strand::wrap()
template <typename Handler> 
Handler custom_alloc(Handler) { ... }
a custom handler that appropriate chains invocations of asio_handler_invoke():
template <class Handler>
class custom_handler
{
public:
  custom_handler(Handler handler)
    : handler_(handler)
  {}
  template <class... Args>
  void operator()(Args&&... args)
  {
    handler_(std::forward<Args>(args)...);
  }
  template <typename Function>
  friend void asio_handler_invoke(
    Function intermediate_handler,
    custom_handler* my_handler)
  {
    // Support chaining custom strategies incase the wrapped handler
    // has a custom strategy of its own.
    using boost::asio::asio_handler_invoke;
    asio_handler_invoke(intermediate_handler, &my_handler->handler_);
  }
private:
  Handler handler_;
};
template <typename Handler>
custom_handler<Handler> custom_alloc(Handler handler)
{
  return {handler};
}
See this answer for more details on strands, and this answer for details on asio_handler_invoke.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With