Função KeWaitForMultipleObjects (wdm.h)

A rotina KeWaitForMultipleObjects coloca o thread atual em um estado de espera alertável ou não inerte até que qualquer um ou todos os vários objetos dispatcher sejam definidos como um estado sinalizado ou (opcionalmente) até que a espera exceda.

Sintaxe

NTSTATUS
KeWaitForMultipleObjects (
    ULONG Count,
    PVOID Object[],
    WaitType,
    KWAIT_REASON WaitReason,
    KPROCESSOR_MODE WaitMode,
    BOOLEAN Alertable,
    PLARGE_INTEGER Timeout,
    PKWAIT_BLOCK WaitBlockArray
    );

Parâmetros

[in] Count

O número de objetos a serem aguardados. Esse parâmetro especifica o número de elementos na matriz apontada pelo parâmetro Object .

[in] Object

Um ponteiro para uma matriz de ponteiros para objetos dispatcher (eventos, mutexes, semáforos, threads e temporizadores) para os quais o chamador fornece o armazenamento. A matriz de ponteiro e os objetos dispatcher devem residir na memória do sistema nãopagada. Para obter mais informações, consulte Comentários.

[in] WaitType

O tipo de operação de espera a ser executada. Especifique WaitAll, indicando que todos os objetos especificados devem atingir um estado sinalizado antes que a espera seja atendida; ou WaitAny, indicando que qualquer um dos objetos deve atingir um estado sinalizado antes que a espera seja atendida.

[in] WaitReason

O motivo da espera. Os drivers devem definir esse valor como Executivo ou, se o driver estiver trabalhando em nome de um usuário e estiver em execução no contexto de um thread de usuário, como UserRequest.

[in] WaitMode

Se o chamador aguarda em KernelMode ou UserMode. Os drivers intermediários e de nível mais baixo devem especificar KernelMode. Se o conjunto de objetos aguardados incluir um mutex, o chamador deverá especificar KernelMode.

[in] Alertable

Um valor booliano que indica se o thread pode ser alertado enquanto está no estado de espera.

[in, optional] Timeout

Um ponteiro para um valor de tempo limite que especifica o tempo absoluto ou relativo, em unidades de 100 nanossegundos, em que a espera deve ser concluída.

Um valor positivo especifica uma hora absoluta, em relação a 1º de janeiro de 1601. Um valor negativo especifica um intervalo relativo à hora atual. Os tempos de expiração absolutos acompanham as alterações na hora do sistema; os tempos de expiração relativos não são afetados pelas alterações de tempo do sistema.

Se *Timeout = 0, a rotina retornará sem esperar. Se o chamador fornecer um ponteiro NULL , a rotina aguardará indefinidamente até que qualquer ou todos os objetos dispatcher sejam definidos como o estado sinalizado. Para obter mais informações, consulte a seção Comentários a seguir.

[out, optional] WaitBlockArray

Um ponteiro para uma matriz de KWAIT_BLOCK alocada pelo chamador. Se Count<= THREAD_WAIT_OBJECTS, WaitBlockArray poderá ser NULL. Caso contrário, esse parâmetro deve apontar para um buffer de memória de sizeof(KWAIT_BLOCK) * Bytes de contagem . A rotina usa esse buffer para manter registros enquanto executa a operação de espera. O buffer WaitBlockArray deve residir na memória do sistema nãopagada. Para obter mais informações, consulte Comentários.

Retornar valor

KeWaitForMultipleObjects pode retornar um dos seguintes:

Código de retorno Descrição
STATUS_SUCCESS O chamador especificou WaitAll para o parâmetro WaitType e todos os objetos dispatcher na matriz Object foram definidos como o estado sinalizado.
STATUS_ALERTED A espera foi interrompida para entregar um alerta ao thread de chamada.
STATUS_USER_APC A espera foi interrompida para entregar uma APC (chamada de procedimento assíncrono) do usuário ao thread de chamada.
STATUS_TIMEOUT Ocorreu um tempo limite antes que o conjunto especificado de condições de espera fosse atendido. Esse valor pode ser retornado quando um valor de tempo limite explícito de zero é especificado, mas o conjunto especificado de condições de espera não pode ser atendido imediatamente.
STATUS_WAIT_0 por meio de STATUS_WAIT_63 O chamador especificou WaitAny para WaitType e um dos objetos dispatcher na matriz Object foi definido como o estado sinalizado. Os seis bits inferiores do valor retornado codificam o índice baseado em zero do objeto que atendeu à espera.
STATUS_ABANDONED_WAIT_0 por meio de STATUS_ABANDONED_WAIT_63 O chamador tentou aguardar um mutex que foi abandonado. Os seis bits inferiores do valor retornado codificam o índice baseado em zero do mutex na matriz Object .

Observe que a macro NT_SUCCESS reconhece todos esses valores de status como valores de "êxito".

Comentários

Cada objeto de thread tem uma matriz interna de blocos de espera que podem ser usados para aguardar vários objetos serem definidos simultaneamente. Sempre que possível, a matriz interna de blocos de espera deve ser usada em uma operação de espera múltipla porque nenhum armazenamento de bloco de espera adicional precisa ser alocado e desalocado posteriormente. No entanto, se o número de objetos que devem ser aguardados simultaneamente for maior do que o número de blocos de espera internos, use o parâmetro WaitBlockArray para especificar um conjunto alternativo de blocos de espera a serem usados na operação de espera. Os drivers só precisam alocar um buffer de memória suficientemente grande para WaitBlockArray. O buffer não precisa ser inicializado; no entanto, ele deve ser alocado da memória do sistema nãopagada. Se o parâmetro WaitMode for UserMode, o buffer WaitBlockArray não deverá ser alocado na pilha local porque a pilha pode ser trocada para fora da memória. Os drivers podem tratar esse buffer como uma estrutura opaca e podem liberá-lo após o retorno da rotina. Se Count> MAXIMUM_WAIT_OBJECTS ou se WaitBlockArray for NULL e Count> THREAD_WAIT_OBJECTS, o sistema emitirá 0xC de Verificação de Bugs (MAXIMUM_WAIT_OBJECTS_EXCEEDED).

O estado atual de cada um dos objetos especificados é examinado para determinar se a espera pode ser atendida imediatamente. Se os efeitos colaterais necessários forem executados nos objetos, um valor apropriado será retornado.

Se a espera não puder ser atendida imediatamente e nenhum valor de tempo limite ou um valor de tempo limite diferente de zero tiver sido especificado, o thread atual será colocado em um estado de espera e um novo thread será selecionado para execução no processador atual. Se nenhum Tempo Limite for fornecido, o thread de chamada permanecerá em um estado de espera até que as condições especificadas por Object e WaitType sejam atendidas.

Se Timeout for especificado, a espera será atendida automaticamente se nenhuma das condições de espera especificadas for atendida quando o intervalo determinado expirar.

Um valor de tempo limite zero permite o teste de um conjunto de condições de espera, executando condicionalmente quaisquer efeitos colaterais se a espera puder ser atendida imediatamente, como na aquisição de um mutex.

Os intervalos de tempo limite são medidos em relação ao relógio do sistema e a precisão com que o sistema operacional pode detectar o fim de um intervalo de tempo limite é limitada pela granularidade do relógio do sistema. Para obter mais informações, consulte Precisão do temporizador.

O parâmetro Alertable determina quando o thread pode ser alertado e seu estado de espera, consequentemente, anulado. Para obter informações adicionais, consulte Esperas e APCs.

A matriz apontada pelo parâmetro Objects deve residir na memória do sistema nãopagada. Normalmente, um driver aloca o armazenamento para a matriz Objects na pilha local. A matriz Objects pode ser alocada na pilha local, independentemente do valor do parâmetro WaitMode .

Os objetos dispatcher apontados pelos elementos na matriz Objects devem residir na memória do sistema nãopagada. Se o parâmetro WaitMode for UserMode, a pilha de kernel poderá ser trocada durante a espera. Consequentemente, um chamador nunca deve tentar passar parâmetros na pilha ao chamar KeWaitForMultipleObjects com o argumento UserMode . Se você alocar o evento na pilha, deverá definir o parâmetro WaitMode como KernelMode.

Uma consideração especial se aplica quando o parâmetro Object passado para KeWaitForMultipleObjects é um mutex. Se o objeto dispatcher aguardado for um mutex, a entrega de APC será a mesma de todos os outros objetos dispatcher durante a espera. No entanto, depois que KeWaitForMultipleObjects retorna com STATUS_SUCCESS e o thread realmente mantém o mutex, somente APCs especiais no modo kernel são entregues. A entrega de todas as outras APCs, tanto no modo kernel quanto no modo de usuário, está desabilitada. Essa restrição na entrega de APCs persiste até que o mutex seja liberado.

É especialmente importante marcar o valor retornado de KeWaitForMultipleObjects quando o parâmetro WaitMode for UserMode ou Alertable for TRUE, pois KeWaitForMultipleObjects pode retornar antecipadamente com um status de STATUS_USER_APC ou STATUS_ALERTED.

Todas as esperas de longo prazo que podem ser anuladas por um usuário devem ser esperas UserMode e Alertable deve ser definida como FALSE.

Sempre que possível, Alertable deve ser definido como FALSE e WaitMode deve ser definido como KernelMode, a fim de reduzir a complexidade do driver. A exceção principal a isso é quando a espera é uma espera de longo prazo.

Um mutex pode ser adquirido recursivamente apenas tempos MINLONG. Se esse limite for excedido, a rotina gerará uma exceção STATUS_MUTANT_LIMIT_EXCEEDED.

Os chamadores de KeWaitForMultipleObjects podem estar em execução em IRQL <= DISPATCH_LEVEL. No entanto, se Timeout = NULL ou *Timeout != 0, o chamador deverá estar em execução em IRQL <= APC_LEVEL e em um contexto de thread não secundário. (Se Timeout != NULL e *Timeout = 0, o chamador deverá estar em execução em IRQL <= DISPATCH_LEVEL.)

Requisitos

Requisito Valor
Cliente mínimo com suporte Disponível a partir do Windows 2000.
Plataforma de Destino Universal
Cabeçalho wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
Biblioteca NtosKrnl.lib
DLL NtosKrnl.exe
IRQL Consulte a seção Observações.
Regras de conformidade da DDI HwStorPortProhibitedDIs(storport), IrpProcessingComplete(wdm), IrqlKeWaitForMultipleObjects(wdm), SpNoWait(storport)

Confira também

ExInitializeFastMutex

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForSingleObject