2016-09-27 62 views
1

我正在阅读Boost.Asio源代码,但存在我感到困惑的代码。有没有人帮助解释为更好的理解,或一些材料,我可以参考理解?谢谢。关于创建boost.asio async_xxxx处理程序对象

的实际代码:

// Wait until data can be received without blocking. 
    template <typename Handler> 
    void async_receive_from(implementation_type& impl, 
     const null_buffers&, endpoint_type& sender_endpoint, 
     socket_base::message_flags flags, Handler& handler) 
    { 
    bool is_continuation = 
     boost_asio_handler_cont_helpers::is_continuation(handler); 

    // Allocate and construct an operation to wrap the handler. 
    typedef reactive_null_buffers_op<Handler> op; 
    typename op::ptr p = { boost::asio::detail::addressof(handler), 
     boost_asio_handler_alloc_helpers::allocate(
     sizeof(op), handler), 0 }; 
    p.p = new (p.v) op(handler); 

    BOOST_ASIO_HANDLER_CREATION((p.p, "socket", 
      &impl, "async_receive_from(null_buffers)")); 

    // Reset endpoint since it can be given no sensible value at this time. 
    sender_endpoint = endpoint_type(); 

    start_op(impl, 
     (flags & socket_base::message_out_of_band) 
      ? reactor::except_op : reactor::read_op, 
     p.p, is_continuation, false, false); 
    p.v = p.p = 0; 
    } 

尤其是对:

typedef reactive_null_buffers_op<Handler> op; 
typename op::ptr p = { boost::asio::detail::addressof(handler), 
    boost_asio_handler_alloc_helpers::allocate(
    sizeof(op), handler), 0 }; 
p.p = new (p.v) op(handler); 

感谢。

+0

你能更具体 - 哪些位不理解? –

回答

0

嗯..请参阅...您试图了解reactive_socket_service类的功能async_receive_from。具体来说,需要null_buffer

功能的签名:

template <typename Handler> 
    void async_receive_from(implementation_type& impl, 
          const null_buffers&, 
          endpoint_type& sender_endpoint, 
          socket_base::message_flags flags, 
          Handler& handler) 

现在,什么是null_buffers的重要性?

简而言之,它基本上允许在被调用的回调中执行缓冲区管理,而不是在提供缓冲区时调用async_receive_from,就像在其他过载中一样。
有关其用例的更详细说明,请参阅THIS答案。

什么是reactive_null_buffers_op<Handler> op

既然你是在这一点上,我假设你知道在asio中的operation类。简而言之,当特定操作完全执行时,它基本上会调用用户提供的回调函数。请在scheduler_operation.hpp中查找scheduler_operation::complete

reactive_null_buffers_op源自scheduler_operation(通过reactive_op)并且它还存储传递给async_receive_from的处理程序的副本。实际的细节有点复杂和有用。现在知道这个类的do_complete方法就是处理程序的上调可能就足够了。

什么是typename op::ptr

寻找ASIO_DEFINE_HANDLER_PTRhandler_alloc_helpers.hpp。简而言之,它是一个持有传递给异步函数的处理程序的结构。 ASIO需要在堆(或通过自定义分配器)上分别分配处理程序,以确保其在套接字接收操作完成期间存在。这是下面两行有哪些呢:

typename op::ptr p = { boost::asio::detail::addressof(handler), 
     boost_asio_handler_alloc_helpers::allocate(
     sizeof(op), handler), 0 }; 
    p.p = new (p.v) op(handler); 

我们通过placement new(2号线)创建的reactive_null_buffers_op<Handler>的分配空间的实例。

现在呢?

一个ASIO存储了用户传递的处理程序对象,它需要在套接字上启动主要的读取操作。为此,它调用start_op函数。 start_op的详细信息超出了问题的当前范围。因此,简而言之,start_op最终注册到轮询器的套接字,例如epoll。我们的处理程序,现在在op,当读取操作准备好执行时,最终会被调用(跳过了大量的细节)。