Função FsRtlCancellableWaitForMultipleObjects (ntifs.h)

A rotina FsRtlCancellableWaitForMultipleObjects executa uma operação de espera cancelável (uma espera que pode ser encerrada) em um ou mais objetos dispatcher.

Sintaxe

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
);

Parâmetros

[in] Count

O número de objetos a serem aguardados.

[in] ObjectArray

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.

[in] WaitType

WaitAll, que indica que todos os objetos especificados devem atingir um estado sinalizado antes que a espera seja atendida; ou WaitAny, que indica que qualquer um dos objetos deve alcançar um estado sinalizado antes que a espera seja atendida.

[in, optional] Timeout

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

Se Timeout apontar para um valor zero (ou seja, *Timeout == 0), a rotina retornará sem esperar. Se o chamador fornecer um ponteiro NULL (ou seja, Timeout == NULL), a rotina aguardará indefinidamente até que qualquer ou todos os objetos do dispatcher sejam definidos como o estado sinalizado.

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 for especificado, a espera será atendida automaticamente se nenhuma das condições de espera especificadas for atendida quando o intervalo especificado expirar.

Um valor de tempo limite zero (ou seja, *Timeout == 0) permite testar um conjunto de condições de espera e executar condicionalmente quaisquer ações adicionais se a espera puder ser atendida imediatamente, como na aquisição de um mutex.

[in, optional] WaitBlockArray

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 * Count) bytes. A rotina usa esse buffer para manter registros enquanto executa a operação de espera.

[in, optional] Irp

Um ponteiro para o IRP original que corresponde à operação de E/S emitida pelo usuário e que pode ser cancelada pelo usuário. O chamador deve garantir que o IRP permanecerá válido durante essa rotina e que o IRP não deve ter um conjunto de rotina de cancelamento (por exemplo, IoSetCancelRoutine não deve ter sido chamado no IRP). Observe que o IRP deve ser mantido pelo chamador, ele não pode ser passado para um driver de nível inferior.

Retornar valor

FsRtlCancellableWaitForMultipleObjects pode retornar um dos seguintes valores:

Código de retorno Descrição
STATUS_SUCCESS O chamador especificou WaitAll para o parâmetro WaitType e todos os objetos dispatcher na matriz ObjectArray foram definidos como o estado sinalizado.
STATUS_TIMEOUT Ocorreu um tempo limite antes que o conjunto especificado de condições de espera fosse atendido. Esse valor pode ser retornado quando o conjunto especificado de condições de espera não pode ser atendido imediatamente e Timeout é definido como zero.
STATUS_WAIT_0 por meio de STATUS_WAIT_63 O chamador especificou WaitAny para WaitType e um dos objetos dispatcher na matriz ObjectArray 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 esperar por um mutex que foi abandonado. Os seis bits inferiores do valor retornado codificam o índice baseado em zero do mutex na matriz ObjectArray .
STATUS_CANCELLED A espera foi interrompida por uma solicitação de cancelamento pendente no IRP especificado. Observe que esse valor será retornado somente se um IRP válido for passado para FsRtlCancellableWaitForMultipleObjects e o IRP for cancelado por CancelSynchronousIo.
STATUS_THREAD_IS_TERMINATING A espera foi interrompida porque o thread foi encerrado por um aplicativo ou pelo usuário.

O valor retornado indica apenas o status da espera. Se aplicável, o status real da solicitação de E/S deve ser obtido diretamente de outro IRP gerado no processo de manipulação do IRP do modo de usuário original.

Observe que a macro NT_SUCCESS retorna FALSE ("failure") para os valores STATUS_CANCELLED e STATUS_THREAD_IS_TERMINATING status e TRUE ("success") para todos os outros valores de status.

Comentários

A rotina FsRtlCancellableWaitForMultipleObjects executa uma operação de espera cancelável em objetos dispatcher. Se o thread for encerrado pelo usuário ou pelo aplicativo ou se CancelSynchronousIo postar uma solicitação de cancelamento em um IRP threaded (IRP síncrono) associado ao thread, a espera será cancelada.

A rotina FsRtlCancellableWaitForMultipleObjects foi projetada para dar suporte às Diretrizes de Conclusão/Cancelamento de E/S a partir do Windows Vista. O objetivo dessas diretrizes é permitir que os usuários (ou aplicativos) encerrem rapidamente os aplicativos. Isso, por sua vez, requer que os aplicativos tenham a capacidade de encerrar rapidamente threads que estão executando E/S, bem como quaisquer operações de E/S atuais. Essa rotina fornece uma maneira de os threads de usuário bloquearem (ou seja, aguardarem) no kernel para conclusão de E/S, objetos dispatcher ou variáveis de sincronização de uma maneira que permita que a espera seja prontamente cancelada. Essa rotina também permite que a espera do thread seja encerrada se o thread for encerrado por um usuário ou um aplicativo.

Por exemplo, um redirecionador pode precisar criar um ou mais IRPs secundários para processar um IRP no modo de usuário e aguardar síncronamente a conclusão dos IRPs secundários. Uma maneira de fazer isso é configurar um evento que será sinalizado pela rotina de conclusão do IRP secundário e aguardar o evento ser sinalizado. Em seguida, para executar uma operação de espera cancelável, FsRtlCancellableWaitForMultipleObjects é chamado passando o evento associado ao IRP secundário, bem como o IRP do modo de usuário original. A espera do thread para que o evento seja sinalizado será cancelada se ocorrer um evento de encerramento pendente ou se o IRP do modo de usuário original for cancelado.

Observe que encerrar a espera não cancela automaticamente nenhuma operação de E/S emitida pelo chamador , que deve ser tratada separadamente pelo chamador.

Cada objeto thread tem uma matriz interna de blocos de espera que podem ser usados para aguardar vários objetos 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 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 e os drivers podem tratá-lo como uma estrutura opaca. O buffer pode ser liberado quando a rotina retorna.

Se Count for maior que MAXIMUM_WAIT_OBJECTS ou se WaitBlockArray for NULL e Count for maior que THREAD_WAIT_OBJECTS, o sistema emitirá 0xC de Verificação de Bugs: MAXIMUM_WAIT_OBJECTS_EXCEEDED.

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

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

FsRtlCancellableWaitForMultipleObjects deve ser chamado em IRQL PASSIVE_LEVEL se o parâmetro irp opcional apontar para um IRP válido. Se o parâmetro Irp não for usado, a rotina poderá ser chamada em IRQL menor ou igual a APC_LEVEL. ApCs de kernel normais podem ser desabilitadas pelo chamador, se necessário, chamando as rotinas KeEnterCriticalRegion ou FsRtlEnterFileSystem . No entanto, APCs de kernel especiais não devem ser desabilitadas.

FsRtlCancellableWaitForMultipleObjects será declarado em builds de depuração se o IRQL for maior ou igual a APC_LEVEL e o parâmetro Irp apontar para um IRP válido.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows Vista
Plataforma de Destino Universal
Cabeçalho ntifs.h (inclua Ntifs.h)
Biblioteca NtosKrnl.lib
DLL NtosKrnl.exe
IRQL Consulte a seção Observações.
Regras de conformidade de DDI HwStorPortProhibitedDIs(storport), PowerIrpDDis(wdm), SpNoWait(storport)

Confira também

ExInitializeFastMutex

FsRtlCancellableWaitForSingleObject

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject

KeWaitForMutexObject