Boost.ASIO源码:从async_write看ASIO的异步IO逻辑

本文详细剖析了Boost.ASIO库中的async_write操作,从两个不同版本的async_write接口入手,探讨了其内部如何通过异步循环调用async_write_some实现数据的完整写入。在async_write的过程中,使用了WriteHandler作为回调,并通过模板元编程技术如SFINAE进行重载选择。async_write最终依赖于reactive_socket_service_base的async_send,经过一系列复杂的逻辑,等待套接字变为可写状态后,由epoll_reactor调度执行实际的写入操作。
摘要由CSDN通过智能技术生成

async_write有两个对外接口:

template <typename AsyncWriteStream, typename Allocator, typename WriteHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
    void (boost::system::error_code, std::size_t))  // 这个宏函数得到的就是void
async_write(AsyncWriteStream& s,
    boost::asio::basic_streambuf<Allocator>& b,
    WriteHandler&& handler)
{
   
  return async_write(s, basic_streambuf_ref<Allocator>(b),
      WriteHandler&& (handler));
}

template <typename AsyncWriteStream, typename Allocator,
    typename CompletionCondition, typename WriteHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
    void (boost::system::error_code, std::size_t))  // 同样是void
async_write(AsyncWriteStream& s,
    boost::asio::basic_streambuf<Allocator>& b,
    CompletionCondition completion_condition,
    WriteHandler&& handler)
{
   
  return async_write(s, basic_streambuf_ref<Allocator>(b),
      completion_condition, WriteHandler&& (handler));
}

分别是指定写入的completion_condition与不指定的版本,这2个函数会调用另外2种重载版本的async_write。对于未指定complete_condition的会传入一个类型为transfer_all_t的伪函数:

class transfer_all_t
{
   
public:
  typedef std::size_t result_type;

  template <typename Error>
  std::size_t operator()(const Error& err, std::size_t)
  {
   
    return !!err ? 0 : default_max_transfer_size;
  }
};

简而言之,这个默认completion_condition的意思就是在不报错的情况下把能读的一次读完就行了。

总之不管是否传入completion_condition,最终都会调用到下面这个函数:

template <typename AsyncWriteStream, typename DynamicBuffer,
    typename CompletionCondition, typename WriteHandler>
void async_write(AsyncWriteStream& s,
    DynamicBuffer&& buffers,
    CompletionCondition completion_condition,
    WriteHandler&& handler,
    typename enable_if<
      is_dynamic_buffer<DynamicBuffer>::value
    >::type*)
{
   
  // 对传进来的回调函数类型进行检验
  BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;

  async_completion<WriteHandler,
    void (boost::system::error_code, std::size_t)> init(handler);

  detail::write_dynbuf_op<AsyncWriteStream,  // write_synbuf_op是个伪函数
    typename decay<DynamicBuffer>::type,
      CompletionCondition, BOOST_ASIO_HANDLER_TYPE(
        WriteHandler, void (boost::system::error_code, std::size_t))>(  // 这里实际上就是创建个临时变量调用operator()
          s, DynamicBuffer&& (buffers), // 这行开始下面都是函数调用的参数
            completion_condition, init.completion_handler)(
              boost::system::error_code(), 0, 1);

  return init.result.get(); // get()里面是空的。。
}

下面看write_dynbuf_op源码,这里略去了一堆逻辑简单但很长的构造函数,就是单纯的成员变量赋值:

template <typename AsyncWriteStream, typename DynamicBuffer,
      typename CompletionCondition, typename WriteHandler>
  class write_dynbuf_op
  {
   
  public:
  // 省略构造函数
    void operator()(const boost::system::error_code& ec,
        std::size_t bytes_transferred, int start = 0)
    {
   
      switch (start)
      {
   
        case 1:
        async_write(stream_, buffers_.data(), completion_condition_, write_dynbuf_op&& (*this));
        return; default:
        buffers_.consume(bytes_transferred);
        handler_
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值