Когда отправляются пакеты порта завершения IO, а когда нет? - PullRequest
4 голосов
/ 28 июня 2010

В настоящее время я работаю над механизмом IPC на основе именованных каналов с использованием порта завершения ввода-вывода.

К сожалению, у меня есть некоторые проблемы с документацией msdn, потому что мне совершенно неясно, в каких случаях вызовы ReadFile / WriteFile приводят к завершению пакета.

Случай, когда FALSE возвращается с ERROR_IO_PENDING, ясен, но как насчет возможного случая, когда возвращается ERROR_MORE_DATA? Будет ли в этом случае пакет завершения? Более того, что делать, если возвращаются другие ошибки? В каких случаях мне нужно обрабатывать результат и свободные ресурсы напрямую, а не в обработчике завершения?

Другой случай был бы, если бы ReadFile / WriteFile даже преуспел, что, очевидно, также возможно. MSDN, к счастью, довольно ясно об этом здесь :

Кроме того, функция WriteFile иногда возвращает TRUE со значением GetLastError ERROR_SUCCESS, даже если она использует асинхронный дескриптор (который также может возвращать FALSE с ERROR_IO_PENDING). ... В этом примере рекомендуется разрешить подпрограмме порта завершения нести полную ответственность за все операции освобождения таких ресурсов.

Правильна ли эта рекомендация во всех случаях, и результат операции ReadFile / WriteFile для дескрипторов, назначенных порту завершения, может (и должен) фактически игнорироваться полностью, поскольку пакет все равно отправляется в порт?

Ответы [ 2 ]

3 голосов
/ 31 марта 2011

Будет элемент завершения ввода-вывода, поставленный в очередь для операции ввода-вывода, всякий раз, когда операция ввода-вывода может начаться.Независимо от того, возникла ошибка или нет после начала операции ввода-вывода, элемент завершения будет поставлен в очередь на порт завершения.

Существует проблема с отображением между кодами NTSTATUS, возвращаемыми системой ввода-вывода и Win32коды ошибок, из-за которых сложно определить, какие состояния являются ошибками, а какие только информационными.NTSTATUS, который используется ядром и собственным API, имеет четыре уровня серьезности: успех, информация, предупреждение и ошибка.Все, кроме кода ошибки, может указывать на то, что операция ввода-вывода могла начаться.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. См. ntstatus.h в SDK платформы или в вашей установке VS, чтобы определить степень серьезностиNTSTATUS код:.

Возможно выполнение операции ввода-вывода при возврате исходного вызова API, например, запрос на чтение, который был только что скопирован из кэша (асинхронно ждать нечего).Сообщение о завершении все еще будет поставлено в очередь в таких случаях для согласованности.

1 голос
/ 31 марта 2011
  • Да, вполне возможно, что ERROR_MORE_DATA может появиться в пакете завершения.Вы всегда должны быть готовы к любым возможным ошибкам.В документации для GetQueuedCompletionStatus ясно, что когда он возвращает FALSE, вы должны проверить, является ли параметр lpOverlapped NULL.Если это не NULL, пакет завершения ввода / вывода содержит ошибку.

  • Поведение по умолчанию для пакета завершения помещается в очередь до порта завершения, даже когда ReadFile или WriteFile возврат TRUE.Начиная с Windows Vista, эту политику можно изменить.См. Документацию по SetFileCompletionNotificationModes.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...