正在检测CancelIoEx是否同步取消

Detecting if CancelIoEx canceled synchronously

本文关键字:同步 取消 是否 CancelIoEx 检测      更新时间:2023-10-16

我正在将每个异步操作的超时添加到基于IOCP的网络中,这样我就可以在C++中使用与Java的NIO.2类似的接口。我已经用一个支持随机访问删除的超时优先级队列实现了这一点(这样,当操作成功完成时,我可以删除其相关的超时)。

我的问题是如何处理超时的发生。现在我调用CancelIoEx,其重叠结构对应于给定的超时。然而,我刚刚在MSDN上读到这篇文章:

如果文件句柄与完成端口相关联,则I/O如果同步操作,则完成数据包不会排队到端口已成功取消。对于仍然挂起的异步操作,取消操作将对I/O完成分组进行排队。

我使用通过完成处理程序扩展的重叠结构(每个操作用户提供的std::函数接受错误代码和写入/读取的字节),每当完成数据包退出队列时都会执行这些处理程序(同样,很像Java的NIO.2 API)。如果取消是异步发生的,那么完成处理程序将照常运行,并获得ERROR_OPERATION_ABORTED。但是,如果CancelIoEx成功地立即取消了操作,该怎么办?根据上面的引用,听起来我需要在这一点上执行处理程序,因为我以后不会得到完成包。但是,我怎么知道是哪种情况,即完成数据包是排队还是立即取消操作???与其他异步操作不同,CancelIoEx不会产生ERROR_IO_PENDING来区分同步和异步完成任务(在本例中为取消)。或者,我是不是读错了,任何重叠的操作都被认为是异步的(注意:我没有设置FILE_SKIP_COMPLETION_PORT_ON_SUCCESS,但这只适用于成功,而不适用于错误,我认为不会影响取消)?

这不是说CancelIoEx是同步还是异步,而是说I/O本身(例如ReadFile)是同步还是同步。它描述了同步操作和异步操作之间的行为差异。

如果文件句柄与完成端口相关联,则I/O如果同步操作已成功取消。对于异步操作仍然挂起,取消操作将排队等待I/O完成小包裹

同步操作——没有OVERLAPPED结构的操作,或者将立即完成的操作——将返回错误ERROR_OPERATION_ABORTED

异步操作——具有无法立即完成的OVERLAPPED结构的操作——将有一个与ERROR_OPERATION_ABORTED一起排队的完成通知。