Função FltCancellableWaitForMultipleObjects (fltkernel.h)

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

Sintaxe

NTSTATUS FLTAPI FltCancellableWaitForMultipleObjects(
  [in]           ULONG              Count,
  [in]           PVOID []           ObjectArray,
  [in]           WAIT_TYPE          WaitType,
  [in, optional] PLARGE_INTEGER     Timeout,
  [in, optional] PKWAIT_BLOCK       WaitBlockArray,
  [in]           PFLT_CALLBACK_DATA CallbackData
);

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

Uma enumeração com o valor de 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 atingir um estado sinalizado antes que a espera seja atendida.

[in, optional] Timeout

Um ponteiro para um valor opcional de tempo limite. Esse parâmetro especifica o tempo absoluto ou relativo em 100 unidades de 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 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 determinado expirar.

Um valor de tempo limite de 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] CallbackData

Um ponteiro para a estrutura FLT_CALLBACK_DATA que representa a operação de E/S emitida pelo usuário e que pode ser cancelada pelo usuário. Esse parâmetro é opcional e pode ser NULL. O chamador deve garantir que a operação de E/S permaneça válida durante essa rotina e que a E/S não deve ter um conjunto de rotina de cancelamento (por exemplo, a função FltSetCancelCompletion não deve ter sido chamada na operação de E/S). Observe que CallbackData deve ser mantido pelo chamador, pois ele não pode ser passado para um driver de nível inferior.

Retornar valor

FltCancellableWaitForMultipleObjects 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 também 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 aguardar 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 na operação de E/S. Observe que esse valor será retornado somente se CallbackData que corresponde a uma operação baseada em IRP for passada para FltCancellableWaitForMultipleObjects e a E/S tiver sido cancelada por uma rotina como FltCancelIo.
STATUS_THREAD_IS_TERMINATING A espera foi interrompida porque um aplicativo ou o usuário encerrou o thread.

O valor retornado indica apenas o status da espera.

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

Comentários

O FltCancellableWaitForMultipleObjects executa uma operação de espera cancelável em objetos dispatcher. Se o usuário ou o aplicativo encerrar o thread ou se uma operação de E/S associada ao thread tiver sido cancelada por uma rotina como FltCancelIo, a espera será cancelada.

A rotina foi projetada para dar suporte às Diretrizes de Conclusão/Cancelamento de E/S. O objetivo dessas diretrizes é permitir que os usuários 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 e 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 uma ou mais operações de E/S secundárias para processar uma E/S no modo de usuário e aguardar de forma síncrona a conclusão das solicitações secundárias. Uma maneira de fazer isso é configurar um evento que será sinalizado pela rotina de conclusão das operações de E/S secundárias e aguardar o evento ser sinalizado. Em seguida, para executar uma operação de espera cancelável, FltCancellableWaitForMultipleObjects é chamado passando os eventos associados às operações de E/S secundárias e a operação de E/S 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 a operação de E/S do modo de usuário original for cancelada.

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 de thread tem uma matriz interna de blocos de espera que você pode usar para aguardar vários objetos simultaneamente. Sempre que possível, você deve usar a matriz interna de blocos de espera 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 você deve aguardar 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. Você não precisa inicializar o buffer e os drivers podem tratá-lo como uma estrutura opaca. Você pode liberar o buffer assim que a rotina retornar.

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

Uma consideração especial se aplica quando um ou mais dos elementos no parâmetro ObjectArray passados para FltCancellableWaitForMultipleObjects se referem a um mutex. Se o objeto dispatcher que é aguardado for um mutex, a entrega de APC será a mesma de todos os outros objetos dispatcher durante a espera. No entanto, depois que FltCancellableWaitForMultipleObjects retorna com STATUS_SUCCESS e o thread realmente conté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.

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

A rotina FltCancellableWaitForMultipleObjects deve ser chamada em IRQL PASSIVE_LEVEL se o parâmetro CallbackData representar um IRP do gerenciador de filtros válido. Caso contrário, a rotina pode 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.

FltCancellableWaitForMultipleObjects será declarado em builds de depuração se CallbackData representar uma operação IRP do Gerenciador de Filtros, mas o IRP na estrutura CallbackData for NULL.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows Vista
Plataforma de Destino Universal
Cabeçalho fltkernel.h (inclua Ntifs.h, Fltkernel.h)
Biblioteca Fltmgr.lib
IRQL Consulte a seção Observações.

Confira também

ExInitializeFastMutex

FltCancelIo

FltCancellableWaitForSingleObject

FltSetCancelCompletion

FsRtlCancellableWaitForMultipleObjects

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject