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的文檔。