`stream.async_read_some(null_buffers,handler)`应该立即完成吗?

时间:2017-10-06 17:59:32

标签: c++ boost-asio

上下文:我正在与Boost ASIO集成的RDMA包装器库上实现一个简单的流适配器。

我遇到的问题是,即使流已返回足够的数据来填充缓冲区,客户端代码调用的boost::asio::async_read聚合器也会挂起,如果内部接收中没有更多待处理数据缓冲。调试似乎表明它正在使用大小为0的单个缓冲区调用流适配器的async_read_some方法。

我发现的文档似乎与该操作是否应该立即完成相矛盾。一方面,the AsyncReadStream concept specification说:

  

如果序列mb中所有缓冲区的总大小为0,则异步读取操作应立即完成,并将0作为参数传递给指定读取的字节数的处理程序。

另一方面,the overview of boost::asio::null_buffers说:

  

在I / O对象“准备好”执行操作之前,null_buffers操作不会返回。

(事实上,在其他地方,我依靠它来注册处理程序,当rdma_cm和ibverbs完成通道FD指示可用事件时调用处理程序。)但是看看null_buffers的实现,它似乎是它只是一个不包含缓冲区的静态对象,因此似乎满足所有缓冲区总大小为0的序列条件。

所以,我很困惑我的async_read_some方法应该如何处理尝试读取0字节的情况。作为一个疯狂的猜测,也许它应该是这样的:在一个真正的空序列如null_buffers它应该只在接收缓冲区中有可用数据时完成,而如果它有一个非空序列,总长度为缓冲区等于0然后它应该立即完成,无论接收缓冲区的状态如何?

1 个答案:

答案 0 :(得分:0)

注意 null_buffers自Boost 1.66.0以来已被弃用:"(Deprecated: Use the socket/descriptor wait() and async_wait() member functions.)"

  

作为一个疯狂的猜测,也许它应该是这样的:在一个真正空的序列,如null_buffers它应该只在接收缓冲区中有可用的数据时完成,而如果它有一个非空的序列缓冲区的长度等于0,那么它应该立即完成,而不管接收缓冲区的状态如何?

没有。 null_buffers不是"空缓冲区"或"零长度缓冲区"。它没有缓冲区",向ASIO例程发信号通知没有缓冲区(因此逻辑上认为大小不是零)。

与缓冲区大小有关的所有完成注释都是无关紧要的,因为不存在缓冲区。相关文档是 Reactor Style Operations

你说的正确:传递null_buffers信号你希望反应堆式操作编织到asio事件子系统中(意思是,你可以异步等待套接字准备好读/写,然后执行实际的IO,例如将底层套接字句柄传递给本身不支持异步IO的第三方API。

相关问题