Reputation: 547
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?)
Upvotes: 4
Views: 2765
Reputation: 51971
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
.
Upvotes: 9
Reputation: 7357
UPD: This answer is wrong=) For anyone interested you can check details in the tail of comments, thanks to Tanner Sansbury.
No. This guarantees your completion handler will be called with strand lock. This not includes calls to async_write_some
.
Also boost::asio does not have something like "write queue" and you need to manage async_write
calls in order to prevent writing mixed content.
Upvotes: 4