2

我目前正在使用IO完成端口基于命名管道的IPC机制。何时发送IO完成端口数据包,何时不完成?

不幸的是,我有一些msdn文档的麻烦,因为我很不清楚在哪些情况下调用ReadFile/WriteFile导致完成数据包。

用ERROR_IO_PENDING返回FALSE的情况很明显,但是当返回ERROR_MORE_DATA时显然可能出现这种情况呢?在这种情况下是否会有完成数据包?而且,如果返回其他错误呢? 在哪些情况下我必须直接处理结果和释放资源,而不是在完成处理程序中?

另一种情况是,如果ReadFile/WriteFile甚至成功,这显然也是可能的。 MSDN是幸运的是了解这个here很清楚:

此外,WriteFile函数有时会返回TRUE与ERROR_SUCCESS的GetLastError函数值,即使它是使用异步手柄(也可返回FALSE与ERROR_IO_PENDING)。 ...在这个例子中,建议是允许完成端口例程全权负责这些资源的所有释放操作。

这是建议在所有情况下是正确的,并且ReadFile的/ WriteFile的工作分配给完成端口句柄的结果可以(也应该)实际上被完全忽略,因为数据包被发送到端口反正?

回答

2

只要IO操作能够启动,IO操作就会排队等待IO操作。无论IO操作开始后是否遇到错误,完成项目都将排队到完成端口。

IO系统返回的NTSTATUS代码与Win32错误代码之间存在映射问题,这使得很难判断哪些状态是错误,哪些只是信息性的。内核和本地API使用的内核版本NTSTATUS有四个严重级别:成功,信息,警告和错误。除了错误代码之外的任何内容都会表明IO操作能够启动。 Win32只有一个严重性(ERROR_*),所以成功,信息和警告代码必须与错误代码一起映射。

  • ERROR_IO_PENDING - STATUS_PENDING是成功的状态
  • ERROR_MORE_DATA - STATUS_BUFFER_OVERFLOW警告或STATUS_MORE_ENTRIES成功状态

可以忽略任何非错误代码是的ReadFile或WriteFile的回报,并期望排队完成项目,但确定哪一个可能有点痛苦。如果Win32错误代码组织得更好,那将会很好,但是Microsoft确实提供了从NTSTATUS到Win32错误代码的映射:http://support.microsoft.com/kb/113996。请参阅平台SDK或VS安装中的ntstatus.h以确定NTSTATUS代码的严重程度。

当原始API调用返回时,IO操作可能会完成,例如,一个刚刚从缓存中复制出来的读请求(不需要异步等待)。为了保持一致性,完成消息仍然会在这种情况下排队。

0
  • 是的,ERROR_MORE_DATA完全可能出现在完成数据包中。你应该随时准备处理任何潜在的错误。在为GetQueuedCompletionStatus的文档很显然,当它返回FALSE,你应该检查lpOverlapped参数NULL。如果它不是NULL,则I/O完成数据包包含错误。

  • 即使当ReadFileWriteFile返回TRUE,默认行为是完成数据包排队到完成端口。从Windows Vista开始,可以更改此策略。请参阅SetFileCompletionNotificationModes的文档。