Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
612 views
in Technique[技术] by (71.8m points)

c++ - asio::async_write and strand

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...