Функция FsRtlCancellableWaitForMultipleObjects (ntifs.h)

Подпрограмма FsRtlCancellableWaitForMultipleObjects выполняет операцию отменяемого ожидания (ожидание, которое может быть завершено) для одного или нескольких объектов диспетчера.

Синтаксис

NTSTATUS FsRtlCancellableWaitForMultipleObjects(
  [in]           ULONG          Count,
  [in]           PVOID []       ObjectArray,
  [in]           WAIT_TYPE      WaitType,
  [in, optional] PLARGE_INTEGER Timeout,
  [in, optional] PKWAIT_BLOCK   WaitBlockArray,
  [in, optional] PIRP           Irp
);

Параметры

[in] Count

Количество объектов для ожидания.

[in] ObjectArray

Указатель на массив указателей на объекты диспетчера (события, мьютексы, семафоры, потоки и таймеры), для которых вызывающий объект предоставляет хранилище.

[in] WaitType

Либо WaitAll, который указывает, что все указанные объекты должны достичь состояния сигнала, прежде чем будет выполнено ожидание; или WaitAny, который указывает, что любой из объектов должен достичь состояния сигнала, прежде чем ожидание будет удовлетворено.

[in, optional] Timeout

Указатель на необязательное значение времени ожидания. Этот параметр задает абсолютное или относительное время в 100 единицах наносекунд, в течение которого должно быть завершено ожидание.

Если timeout указывает на нулевое значение (т. е. *Timeout == 0), подпрограмма возвращается без ожидания. Если вызывающий объект предоставляет указатель NULL (то есть Timeout == NULL), подпрограмма ожидает неограниченное время, пока любой или все объекты диспетчера не будут заданы в состояние сигнала.

Положительное значение указывает абсолютное время относительно 1 января 1601 года. Отрицательное значение указывает интервал относительно текущего времени. Абсолютное время окончания срока действия отслеживает любые изменения системного времени; изменения системного времени не влияют на относительный срок действия.

Если указано время ожидания , ожидание будет автоматически выполнено, если ни одно из указанных условий ожидания не будет выполнено по истечении заданного интервала.

Значение времени ожидания, равное нулю (т. е. *Timeout == 0), позволяет протестировать набор условий ожидания и условно выполнять любые дополнительные действия, если ожидание может быть немедленно выполнено, как при приобретении мьютекса.

[in, optional] WaitBlockArray

Если count<= THREAD_WAIT_OBJECTS, WaitBlockArray может иметь значение NULL. В противном случае этот параметр должен указывать на буфер памяти из sizeof(KWAIT_BLOCK * Count) байтов. Подпрограмма использует этот буфер для хранения записей при выполнении операции ожидания.

[in, optional] Irp

Указатель на исходную IRP, соответствующую операции ввода-вывода, которая была выдана пользователем и может быть отменена пользователем. Вызывающий объект должен убедиться, что IRP будет оставаться действительным в течение всего срока действия этой процедуры и что IRP не должен иметь набор подпрограмм отмены (например, IoSetCancelRoutine не должен вызываться для IRP). Обратите внимание, что IRP должен храниться вызывающим абонентом. Его нельзя передать драйверу более низкого уровня.

Возвращаемое значение

FsRtlCancellableWaitForMultipleObjects может возвращать одно из следующих значений:

Код возврата Описание
STATUS_SUCCESS Вызывающий объект указал WaitAll для параметра WaitType , а все объекты диспетчера в массиве ObjectArray были заданы в состояние сигнала.
STATUS_TIMEOUT Время ожидания истекло до выполнения указанного набора условий ожидания. Это значение может быть возвращено, если указанный набор условий ожидания не может быть немедленно выполнен, а время ожидания равно нулю.
STATUS_WAIT_0 через STATUS_WAIT_63 Вызывающий объект указал WaitAny для WaitType , а для одного из объектов диспетчера в массиве ObjectArray задано состояние сигнала. Нижние шесть битов возвращаемого значения кодируют отсчитываемый от нуля индекс объекта, удовлетворяющего ожиданию.
STATUS_ABANDONED_WAIT_0 через STATUS_ABANDONED_WAIT_63 Вызывающий попытался дождаться оставленного мьютекса. Шесть нижних бит возвращаемого значения кодируют отсчитываемый от нуля индекс мьютекса в массиве ObjectArray .
STATUS_CANCELLED Ожидание было прервано запросом на отмену в указанном IRP. Обратите внимание, что это значение возвращается только в том случае, если допустимая IRP передается в FsRtlCancellableWaitForMultipleObjects и IRP была отменена CancelSynchronousIo.
STATUS_THREAD_IS_TERMINATING Ожидание было прервано, так как поток был прерван приложением или пользователем.

Возвращаемое значение указывает только состояние ожидания. Если это применимо, фактическое состояние запроса ввода-вывода должно быть получено непосредственно из другого IRP, созданного в процессе обработки исходного IRP в пользовательском режиме.

Обратите внимание, что макрос NT_SUCCESS возвращает значение FALSE ("сбой") для STATUS_CANCELLED и STATUS_THREAD_IS_TERMINATING значения состояния и TRUE ("успешно") для всех остальных значений состояния.

Комментарии

Подпрограмма FsRtlCancellableWaitForMultipleObjects выполняет отменяемую операцию ожидания для объектов диспетчера. Если поток завершается пользователем или приложением или если CancelSynchronousIo отправляет запрос на отмену в потоке IRP (синхронной IRP), связанной с потоком, ожидание отменяется.

Подпрограмма FsRtlCancellableWaitForMultipleObjects была разработана для поддержки рекомендаций по завершению и отмене ввода-вывода , начиная с Windows Vista. Цель этих рекомендаций — разрешить пользователям (или приложениям) быстро завершать работу приложений. Это, в свою очередь, требует, чтобы приложения имели возможность быстро завершать потоки, выполняющие операции ввода-вывода, а также любые текущие операции ввода-вывода. Эта подпрограмма позволяет пользовательским потокам блокировать (т. е. ожидать) в ядре для завершения ввода-вывода, объектов диспетчера или переменных синхронизации таким образом, чтобы ожидание было легко отменено. Эта подпрограмма также позволяет завершить ожидание потока, если поток завершается пользователем или приложением.

Например, перенаправлению может потребоваться создать одну или несколько вторичных поставщиков irp, чтобы обработать IRP в пользовательском режиме и синхронно дождаться завершения дополнительных IRP. Один из способов сделать это — настроить событие, которое будет сигнализироваться подпрограммой завершения вторичного IRP, а затем дождаться сигнала о событии. Затем для выполнения операции ожидания с отменой вызывается FsRtlCancellableWaitForMultipleObjects , передавая событие, связанное со вторичной IRP, а также исходный IRP в пользовательском режиме. Ожидание потока сигнала о событии отменяется, если происходит ожидающее событие завершения или если отменен исходный IRP в пользовательском режиме.

Обратите внимание, что прекращение ожидания не отменяет автоматически никаких операций ввода-вывода, выполняемых вызывающим абонентом, которые должны обрабатываться отдельно вызывающим абонентом.

Каждый объект потока имеет встроенный массив блоков ожидания, которые можно использовать для одновременного ожидания нескольких объектов. По возможности встроенный массив блоков ожидания следует использовать в операции ожидания с несколькими ожиданиями, так как дополнительное хранилище блоков ожидания не требуется выделять, а затем освобождается. Однако если количество объектов, которые необходимо ожидать одновременно, превышает количество встроенных блоков ожидания, используйте параметр WaitBlockArray , чтобы указать альтернативный набор блоков ожидания, которые будут использоваться в операции ожидания. Драйверам необходимо выделить достаточно большой буфер памяти для WaitBlockArray. Буфер не нужно инициализировать, и драйверы могут рассматривать его как непрозрачную структуру. Буфер можно освободить после возврата подпрограммы.

Если значение параметра Count больше MAXIMUM_WAIT_OBJECTS или значение WaitBlockArray равно NULL, а значение Count больше THREAD_WAIT_OBJECTS, система выдает 0xC проверки ошибок: MAXIMUM_WAIT_OBJECTS_EXCEEDED.

Особое внимание следует учитывать, если параметр ObjectArray, передаваемыйв FsRtlCancellableWaitForMultipleObjects , является мьютексом. Если объект диспетчера, который ожидается, является мьютексом, доставка APC будет такой же, как и для всех других объектов диспетчера во время ожидания. Однако после того, как FsRtlCancellableWaitForMultipleObjects возвращает STATUS_SUCCESS и поток фактически содержит мьютекс, доставляются только специальные APC в режиме ядра. Доставка всех остальных APC, как в режиме ядра, так и в пользовательском режиме, отключена. Это ограничение на доставку APC сохраняется до освобождения мьютекса.

Мьютекс может быть получен рекурсивно только раз MINLONG. Если это ограничение превышено, подпрограмма вызывает исключение STATUS_MUTANT_LIMIT_EXCEEDED.

FsRtlCancellableWaitForMultipleObjects должен вызываться в IRQL PASSIVE_LEVEL, если необязательный параметр Irp указывает на допустимый IRP. Если параметр Irp не используется, подпрограмма может вызываться в IRQL меньше или равна APC_LEVEL. При необходимости вызывающий объект может отключить обычные APC ядра, вызвав подпрограммы KeEnterCriticalRegion или FsRtlEnterFileSystem . Однако специальные APC ядра не должны быть отключены.

FsRtlCancellableWaitForMultipleObjects будет утверждаться в отладочных сборках, если IRQL больше или равен APC_LEVEL а параметр Irp указывает на допустимый IRP.

Требования

Требование Значение
Минимальная версия клиента Windows Vista
Целевая платформа Универсальное
Верхняя часть ntifs.h (включая Ntifs.h)
Библиотека NtosKrnl.lib
DLL NtosKrnl.exe
IRQL См. раздел "Примечания".
Правила соответствия DDI HwStorPortProhibitedDDIs(storport), PowerIrpDDis(wdm), SpNoWait(storport)

См. также раздел

ExInitializeFastMutex

FsRtlCancellableWaitForSingleObject

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject

KeWaitForMutexObject