Как и в случае функции CreateThread, при вызове которой также указывается имя некоторой функции, имя
Значения параметра dwError ограничены 0 (успешное завершение) и ERROR_HANDLE_EOF (при попытке выполнить чтение с выходом за пределы файла). Структура OVERLAPPED — это та структура, которая использовалась завершившимся вызовом ReadFileEx или WriteFileEx.
Прежде чем процедура завершения будет вызвана системой, должны произойти две вещи:
1. Должна завершиться операция ввода/вывода.
2. Вызывающий поток должен находиться в состоянии дежурного ожидания, извещая систему о том, что требуется выполнить процедуру завершения, находящуюся в очереди.
Каким образом поток переходит в состояние дежурного ожидания? Он должен выполнить явный вызов одной из функций дежурного ожидания, описанных в следующем разделе. Тем самым поток создает условия, делающие преждевременное выполнение процедуры завершения невозможным. В состоянии дежурного ожидания поток может находиться только на протяжении того времени, пока длится вызов функции дежурного ожидания; после возврата из этой функции поток выходит из указанного состояния.
Если оба эти условия удовлетворены, выполняются процедуры завершения, помещенные в очередь в результате завершения операций ввода/вывода.
Функции дежурного ожидания
Всего предусмотрено пять функций дежурного ожидания, но ниже приводятся прототипы только трех из них, которые представляют для нас непосредственный интерес:
DWORD WaitForSingleObjectEx(HANDLE hObject, DWORD dwMilliseconds, BOOL bAlertable)
DWORD WaitForMultipleObjectsEx(DWORD cObjects, LPHANDLE lphObjects, BOOL fWaitAll, DWORD dwMilliseconds, BOOL bAlertable)
DWORD SleepEx(DWORD dwMilliseconds, BOOL bAlertable)
В каждой из функций дежурного ожидания имеется флаг bAlertable, который в случае асинхронного ввода/вывода должен устанавливаться в TRUE. Приведенные выше функции являются расширением знакомых вам функций Wait и Sleep.
Длительность интервалов ожидания указывается, как обычно, в миллисекундах. Каждая из этих трех функций осуществляет возврат, как только наступает
• Дескриптор (дескрипторы) переходит (переходят) в сигнальное состояние, чем удовлетворяются стандартные требования двух из функций ожидания.
• Истекает интервал ожидания.
• Все процедуры завершения, находящиеся в очереди потока, прекращают свое выполнение, а значение параметра bAlertable равно TRUE. Процедура завершения помещается в очередь тогда, когда завершается соответствующая ей операция ввода/вывода (рис. 14.2).
Заметьте, что со структурами OVERLAPPED в функциях ReadFileEx и WriteFileEx не связаны никакие события, поэтому ни один из дескрипторов, указываемых при вызове функции ожидания, не связывается непосредственно с какой-либо определенной операцией ввода/вывода. В то же время, функция SleepEx не связана с объектами синхронизации, и поэтому ее проще всего использовать. В случае функции SleepEx в качестве длительности интервала ожидания обычно указывают значение INFINITE, поэтому возврат из этой функции произойдет только после того, как закончится выполнение одной или нескольких процедур завершения, которые в настоящий момент находятся в очереди.
Выполнение процедуры завершения и возврат из функции дежурного ожидания
По окончании выполнения операции расширенного ввода/вывода связанная с ней процедура завершения со своими аргументами, определяющими структуру OVERLAPPED, счетчик байтов и код ошибки, помещается в очередь для выполнения.