asio::async_write and strand

早过忘川 提交于 2019-11-29 02:38:50
Tanner Sansbury

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!