Funzione KeWaitForMultipleObjects (wdm.h)
La routine KeWaitForMultipleObjects inserisce il thread corrente in uno stato di attesa avvisabile o non attivabile finché uno o tutti gli oggetti dispatcher vengono impostati su uno stato segnalato o (facoltativamente) fino al timeout di attesa.
Sintassi
NTSTATUS
KeWaitForMultipleObjects (
ULONG Count,
PVOID Object[],
WaitType,
KWAIT_REASON WaitReason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout,
PKWAIT_BLOCK WaitBlockArray
);
Parametri
[in] Count
Numero di oggetti da attendere. Questo parametro specifica il numero di elementi nella matrice a cui punta il parametro Object.
[in] Object
Puntatore a una matrice di puntatori a oggetti dispatcher (eventi, mutex, semafori, thread e timer) per cui il chiamante fornisce l'archiviazione. Sia la matrice del puntatore che gli oggetti dispatcher devono risiedere nella memoria di sistema non di paging. Per altre informazioni, vedere Osservazioni.
[in] WaitType
Tipo di operazione di attesa da eseguire. Specificare WaitAll, che indica che tutti gli oggetti specificati devono ottenere uno stato segnalato prima che l'attesa venga soddisfatta; o WaitAny, che indica che uno degli oggetti deve ottenere uno stato segnalato prima che l'attesa venga soddisfatta.
[in] WaitReason
Motivo dell'attesa. I driver devono impostare questo valore su Executive oppure, se il driver sta eseguendo per conto di un utente ed è in esecuzione nel contesto di un thread utente, per UserRequest.
[in] WaitMode
Indica se il chiamante attende KernelMode o UserMode. I driver intermedi e di livello più basso devono specificare KernelMode. Se il set di oggetti in attesa include un mutex, il chiamante deve specificare KernelMode.
[in] Alertable
Valore booleano che indica se il thread può essere avvisato mentre è nello stato di attesa.
[in, optional] Timeout
Puntatore a un valore di timeout che specifica il tempo assoluto o relativo, in unità di 100 nanosecondi, in cui l'attesa deve essere completata.
Un valore positivo specifica un'ora assoluta, rispetto al 1° gennaio 1601. Un valore negativo specifica un intervallo relativo all'ora corrente. I tempi di scadenza assoluti tengono traccia delle modifiche apportate all'ora di sistema; le ore di scadenza relative non sono interessate dalle modifiche all'ora di sistema.
Se *timeout = 0, la routine restituisce senza attendere. Se il chiamante fornisce un puntatore NULL, la routine attende per un periodo illimitato fino a quando uno o tutti gli oggetti dispatcher non vengono impostati sullo stato segnalato. Per altre informazioni, vedere la sezione Osservazioni seguente.
[out, optional] WaitBlockArray
Puntatore a una matrice di KWAIT_BLOCK allocata dal chiamante. Se Count<= THREAD_WAIT_OBJECTS, WaitBlockArray può essere NULL. In caso contrario, questo parametro deve puntare a un buffer di memoria di sizeof(KWAIT_BLOCK) * Conteggio byte. La routine usa questo buffer per mantenere i record durante l'esecuzione dell'operazione di attesa. Il buffer WaitBlockArray deve risiedere nella memoria di sistema non di paging. Per altre informazioni, vedere Osservazioni.
Valore restituito
KeWaitForMultipleObjects può restituire uno dei seguenti elementi:
Codice restituito | Descrizione |
---|---|
STATUS_SUCCESS | Il chiamante specificato WaitAll per il parametro WaitType e tutti gli oggetti dispatcher nella matrice Object sono stati impostati sullo stato segnalato. |
STATUS_ALERTED | L'attesa è stata interrotta per recapitare un avviso al thread chiamante. |
STATUS_USER_APC | L'attesa è stata interrotta per recapitare una chiamata asincrona dell'utente al thread chiamante. |
STATUS_TIMEOUT | Si è verificato un timeout prima che sia stato soddisfatto il set specificato di condizioni di attesa. Questo valore può essere restituito quando viene specificato un valore esplicito di timeout pari a zero, ma non è possibile soddisfare immediatamente il set specificato di condizioni di attesa. |
STATUS_WAIT_0 tramite STATUS_WAIT_63 | Il chiamante specificato WaitAny per WaitType e uno degli oggetti dispatcher nella matrice Object è stato impostato sullo stato segnalato. I sei bit inferiori del valore restituito codificano l'indice in base zero dell'oggetto che ha soddisfatto l'attesa. |
STATUS_ABANDONED_WAIT_0 tramite STATUS_ABANDONED_WAIT_63 | Il chiamante ha tentato di attendere un mutex abbandonato. I sei bit inferiori del valore restituito codificano l'indice in base zero del mutex nella matrice Object. |
Si noti che la macro NT_SUCCESS riconosce tutti questi valori di stato come valori di "operazione riuscita".
Osservazioni
Ogni oggetto thread ha una matrice predefinita di blocchi di attesa che possono essere usati per attendere che diversi oggetti vengano impostati simultaneamente. Quando possibile, la matrice predefinita di blocchi di attesa deve essere usata in un'operazione di attesa multipla perché non è necessario allocare e deallocare in un secondo momento l'archiviazione dei blocchi di attesa aggiuntiva. Tuttavia, se il numero di oggetti da attendere contemporaneamente è maggiore del numero di blocchi di attesa predefiniti, utilizzare il parametro WaitBlockArray per specificare un set alternativo di blocchi di attesa da utilizzare nell'operazione di attesa. I driver devono allocare solo un buffer di memoria sufficientemente grande per WaitBlockArray. Non è necessario inizializzare il buffer; Tuttavia, deve essere allocata dalla memoria di sistema non di paging. Se il parametro WaitMode è UserMode, il buffer WaitBlockArray non deve essere allocato nello stack locale perché lo stack potrebbe essere scambiato fuori memoria. I driver possono trattare questo buffer come una struttura opaca e liberarlo dopo la restituzione della routine. Se Count> MAXIMUM_WAIT_OBJECTS o se WaitBlockArray è NULL e Count> THREAD_WAIT_OBJECTS, il sistema genera 0xC 0xC (MAXIMUM_WAIT_OBJECTS_EXCEEDED).
Lo stato corrente per ognuno degli oggetti specificati viene esaminato per determinare se l'attesa può essere soddisfatta immediatamente. Se gli effetti collaterali necessari vengono eseguiti sugli oggetti, viene restituito un valore appropriato.
Se l'attesa non può essere soddisfatta immediatamente e non è stato specificato alcun valore di timeout o un valore di timeout diverso da zero, il thread corrente viene inserito in uno stato di attesa e viene selezionato un nuovo thread per l'esecuzione nel processore corrente. Se non viene fornito alcun timeout, il thread chiamante rimarrà in uno stato di attesa finché non vengono soddisfatte le condizioni specificate da Object e WaitType.
Se viene specificato timeout, l'attesa verrà soddisfatta automaticamente se nessuna delle condizioni di attesa specificate viene soddisfatta alla scadenza dell'intervallo specificato.
Un valore di timeout pari a zero consente il test di un set di condizioni di attesa, eseguendo in modo condizionale eventuali effetti collaterali se l'attesa può essere soddisfatta immediatamente, come nell'acquisizione di un mutex.
Gli intervalli di timeout vengono misurati in relazione all'orologio di sistema e l'accuratezza con cui il sistema operativo può rilevare la fine di un intervallo di timeout è limitata dalla granularità dell'orologio di sistema. Per altre informazioni, vedere accuratezza timer.
Il parametro Alertable determina quando il thread può essere avvisato e il relativo stato di attesa di conseguenza interrotto. Per altre informazioni, vedere Waits and APCs.
La matrice a cui punta il parametro Objects deve risiedere nella memoria di sistema non di paging. In genere, un driver alloca lo spazio di archiviazione per la matrice Objects nello stack locale. La matrice Objects può essere allocata nello stack locale indipendentemente dal valore del parametro WaitMode.
Gli oggetti dispatcher a cui puntano gli elementi nella matrice oggetti devono risiedere nella memoria di sistema non di paging. Se il parametro WaitMode è UserMode, lo stack del kernel può essere scambiato durante l'attesa. Di conseguenza, un chiamante non deve mai tentare di passare parametri nello stack quando si chiama KeWaitForMultipleObjects con l'argomento UserMode. Se si alloca l'evento nello stack, è necessario impostare il parametro WaitMode su KernelMode.
Una considerazione speciale si applica quando il parametro Object passato a KeWaitForMultipleObjects è un mutex. Se l'oggetto dispatcher in attesa è un mutex, il recapito APC è uguale a quello di tutti gli altri oggetti dispatcher durante l'attesa. Tuttavia, dopo KeWaitForMultipleObjects restituisce con STATUS_SUCCESS e il thread contiene effettivamente il mutex, vengono recapitate solo API speciali in modalità kernel. Il recapito di tutte le altre API, sia in modalità kernel che in modalità utente, è disabilitato. Questa restrizione per il recapito delle API persiste fino al rilascio del mutex.
È particolarmente importante controllare il valore restituito di KeWaitForMultipleObjects quando il parametro WaitMode è UserMode o Alertable è TRUE, perché KeWaitForMultipleObjects potrebbe restituire in anticipo uno stato di STATUS_USER_APC o STATUS_ALERTED.
Tutte le attese a lungo termine che possono essere interrotte da un utente devono essere UserMode attese e Avvisabile deve essere impostata su FALSE.
Laddove possibile, è consigliabile impostare Alertable su FALSE e WaitMode deve essere impostato su KernelModeper ridurre la complessità dei driver. L'eccezione principale è quando l'attesa è un'attesa a lungo termine.
Un mutex può essere acquisito in modo ricorsivo solo volte MINLONG. Se questo limite viene superato, la routine genera un'eccezione STATUS_MUTANT_LIMIT_EXCEEDED.
I chiamanti di KeWaitForMultipleObjects possono essere eseguiti in IRQL <= DISPATCH_LEVEL. Tuttavia, se Timeout = NULL o *Timeout != 0, il chiamante deve essere in esecuzione in IRQL <= APC_LEVEL e in un contesto di thread non arbitro. Se timeout != NULL e *timeout = 0, il chiamante deve essere in esecuzione in irQL <= DISPATCH_LEVEL.
Fabbisogno
Requisito | Valore |
---|---|
client minimo supportato | Disponibile a partire da Windows 2000. |
piattaforma di destinazione | Universale |
intestazione | wdm.h (include Wdm.h, Ntddk.h, Ntifs.h) |
libreria | NtosKrnl.lib |
dll | NtosKrnl.exe |
IRQL | Vedere la sezione Osservazioni. |
regole di conformità DDI | HwStorPortProhibitedDDIs(storport), IrpProcessingComplete(wdm), IrqlKeWaitForMultipleObjects(wdm), SpNoWait(storport) |