Fonction KeWaitForMultipleObjects (wdm.h)

La routine KeWaitForMultipleObjects place le thread actuel dans un état d’attente alertable ou non modifiable jusqu’à ce que tout ou partie d’un certain nombre d’objets de répartiteur soient définis sur un état signalé ou (éventuellement) jusqu’à ce que l’attente expire.

Syntaxe

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

Paramètres

[in] Count

Nombre d’objets à attendre. Ce paramètre spécifie le nombre d’éléments dans le tableau pointé vers le paramètre Object .

[in] Object

Pointeur vers un tableau de pointeurs vers des objets de répartiteur (événements, mutexes, sémaphores, threads et minuteurs) pour lesquels l’appelant fournit le stockage. Le tableau de pointeurs et les objets de répartiteur doivent résider dans la mémoire système non pagée. Pour plus d'informations, consultez la section Notes.

[in] WaitType

Type d’opération d’attente à effectuer. Spécifiez WaitAll, indiquant que tous les objets spécifiés doivent atteindre un état signalé avant que l’attente soit satisfaite ; ou WaitAny, indiquant que l’un des objets doit atteindre un état signalé avant que l’attente soit satisfaite.

[in] WaitReason

La raison de l’attente. Les pilotes doivent définir cette valeur sur Executive ou, si le pilote travaille pour le compte d’un utilisateur et s’exécute dans le contexte d’un thread utilisateur, sur UserRequest.

[in] WaitMode

Indique si l’appelant attend dans KernelMode ou UserMode. Les pilotes intermédiaires et de niveau le plus bas doivent spécifier KernelMode. Si l’ensemble d’objets attendus inclut un mutex, l’appelant doit spécifier KernelMode.

[in] Alertable

Valeur booléenne qui indique si le thread peut être alerté alors qu’il est en attente.

[in, optional] Timeout

Pointeur vers une valeur de délai d’attente qui spécifie l’heure absolue ou relative, en unités de 100 nanosecondes, à laquelle l’attente doit être terminée.

Une valeur positive spécifie une heure absolue, par rapport au 1er janvier 1601. Une valeur négative spécifie un intervalle par rapport à l’heure actuelle. Les heures d’expiration absolues suivent les modifications apportées à l’heure système ; les heures d’expiration relatives ne sont pas affectées par les changements d’heure système.

Si *Délai d’expiration = 0, la routine retourne sans attendre. Si l’appelant fournit un pointeur NULL , la routine attend indéfiniment jusqu’à ce que tous les objets de répartiteur soient définis sur l’état signalé. Pour plus d'informations, consultez la section Notes qui suit.

[out, optional] WaitBlockArray

Pointeur vers un tableau de KWAIT_BLOCK alloué à l’appelant . Si Count<= THREAD_WAIT_OBJECTS, WaitBlockArray peut avoir la valeur NULL. Sinon, ce paramètre doit pointer vers une mémoire tampon de tailleof(KWAIT_BLOCK) * Nombre d’octets . La routine utilise cette mémoire tampon pour la conservation des enregistrements lors de l’exécution de l’opération d’attente. La mémoire tampon WaitBlockArray doit résider dans la mémoire système non pagée. Pour plus d'informations, consultez la section Notes.

Valeur retournée

KeWaitForMultipleObjects peut retourner l’un des éléments suivants :

Code de retour Description
STATUS_SUCCESS L’appelant a spécifié WaitAll pour le paramètre WaitType et tous les objets de répartiteur du tableau d’objets ont été définis sur l’état signalé.
STATUS_ALERTED L’attente a été interrompue pour remettre une alerte au thread appelant.
STATUS_USER_APC L’attente a été interrompue pour remettre un appel de procédure asynchrone utilisateur (APC) au thread appelant.
STATUS_TIMEOUT Un délai d’attente s’est produit avant que l’ensemble de conditions d’attente spécifié ne soit rempli. Cette valeur peut être retournée lorsqu’une valeur de délai d’attente explicite de zéro est spécifiée, mais que l’ensemble de conditions d’attente spécifié ne peut pas être rempli immédiatement.
STATUS_WAIT_0 via STATUS_WAIT_63 L’appelant a spécifié WaitAny pour WaitType et l’un des objets de répartiteur dans le tableau d’objets a été défini sur l’état signalé. Les six bits inférieurs de la valeur de retour encodent l’index de base zéro de l’objet qui a satisfait l’attente.
STATUS_ABANDONED_WAIT_0 via STATUS_ABANDONED_WAIT_63 L’appelant a tenté d’attendre un mutex qui a été abandonné. Les six bits inférieurs de la valeur de retour encodent l’index de base zéro du mutex dans le tableau Object .

Notez que la macro NT_SUCCESS reconnaît toutes ces valeurs status comme des valeurs de « réussite ».

Remarques

Chaque objet thread a un tableau intégré de blocs d’attente qui peut être utilisé pour attendre que plusieurs objets soient définis simultanément. Dans la mesure du possible, le tableau intégré de blocs d’attente doit être utilisé dans une opération d’attente multiple, car aucun stockage de bloc d’attente supplémentaire ne doit être alloué et libéré ultérieurement. Toutefois, si le nombre d’objets qui doivent être attendus simultanément est supérieur au nombre de blocs d’attente intégrés, utilisez le paramètre WaitBlockArray pour spécifier un autre ensemble de blocs d’attente à utiliser dans l’opération d’attente. Les pilotes doivent uniquement allouer une mémoire tampon suffisamment importante pour WaitBlockArray. La mémoire tampon n’a pas besoin d’être initialisée ; toutefois, il doit être alloué à partir de la mémoire système non pagée. Si le paramètre WaitMode est UserMode, la mémoire tampon WaitBlockArray ne doit pas être allouée sur la pile locale, car la pile peut être permutée en mémoire insuffisante. Les pilotes peuvent traiter cette mémoire tampon comme une structure opaque et la libérer après le retour de la routine. Si count> MAXIMUM_WAIT_OBJECTS ou si WaitBlockArray a lavaleur NULL et Count> THREAD_WAIT_OBJECTS, le système émet des 0xC de vérification des bogues (MAXIMUM_WAIT_OBJECTS_EXCEEDED).

L’état actuel de chacun des objets spécifiés est examiné pour déterminer si l’attente peut être satisfaite immédiatement. Si les effets secondaires nécessaires sont effectués sur les objets, une valeur appropriée est retournée.

Si l’attente ne peut pas être satisfaite immédiatement et qu’aucune valeur de délai d’attente ou une valeur de délai d’attente différente de zéro n’a été spécifiée, le thread actuel est placé dans un état d’attente et un nouveau thread est sélectionné pour l’exécution sur le processeur actuel. Si aucun délai d’attente n’est fourni, le thread appelant reste dans un état d’attente jusqu’à ce que les conditions spécifiées par Object et WaitType soient remplies.

Si le délai d’attente est spécifié, l’attente est automatiquement satisfaite si aucune des conditions d’attente spécifiées n’est remplie à l’expiration de l’intervalle donné.

Une valeur de délai d’attente égale à zéro permet de tester un ensemble de conditions d’attente, en effectuant des effets secondaires conditionnels si l’attente peut être immédiatement satisfaite, comme dans l’acquisition d’un mutex.

Les intervalles de délai d’expiration sont mesurés par rapport à l’horloge système, et la précision avec laquelle le système d’exploitation peut détecter la fin d’un intervalle de délai d’expiration est limitée par la granularité de l’horloge système. Pour plus d’informations, consultez Précision du minuteur.

Le paramètre Alertable détermine quand le thread peut être alerté et son état d’attente par conséquent abandonné. Pour plus d’informations, consultez Waits and APCs.

Le tableau pointé par le paramètre Objects doit résider dans la mémoire système non pagée. En règle générale, un pilote alloue le stockage pour le tableau d’objets sur la pile locale. Le tableau Objects peut être alloué sur la pile locale, quelle que soit la valeur du paramètre WaitMode .

Les objets de répartiteur pointés par les éléments du tableau Objets doivent résider dans la mémoire système non pagée. Si le paramètre WaitMode est UserMode, la pile du noyau peut être permutée pendant l’attente. Par conséquent, un appelant ne doit jamais tenter de passer des paramètres sur la pile lors de l’appel de KeWaitForMultipleObjects avec l’argument UserMode . Si vous allouez l’événement sur la pile, vous devez définir le paramètre WaitMode sur KernelMode.

Une considération particulière s’applique lorsque le paramètre Object passé à KeWaitForMultipleObjects est un mutex. Si l’objet de répartiteur attendu est un mutex, la remise APC est la même que pour tous les autres objets de répartiteur pendant l’attente. Toutefois, une fois que KeWaitForMultipleObjects est retourné avec STATUS_SUCCESS et que le thread contient réellement le mutex, seuls les API en mode noyau spéciaux sont fournis. La remise de tous les autres API, en mode noyau et en mode utilisateur, est désactivée. Cette restriction sur la remise des API persiste jusqu’à ce que le mutex soit libéré.

Il est particulièrement important de case activée la valeur de retour de KeWaitForMultipleObjects lorsque le paramètre WaitMode est UserMode ou alertable a la valeur TRUE, car KeWaitForMultipleObjects peut revenir tôt avec un status de STATUS_USER_APC ou STATUS_ALERTED.

Toutes les attentes à long terme qui peuvent être abandonnées par un utilisateur doivent être des attentes UserMode et Alertable doit avoir la valeur FALSE.

Si possible, Alertable doit avoir la valeur FALSE et WaitMode doit être défini sur KernelMode, afin de réduire la complexité du pilote. La principale exception à cela est lorsque l’attente est une attente à long terme.

Un mutex ne peut être acquis de manière récursive que des fois MINLONG. Si cette limite est dépassée, la routine déclenche une exception STATUS_MUTANT_LIMIT_EXCEEDED.

Les appelants de KeWaitForMultipleObjects peuvent s’exécuter sur IRQL <= DISPATCH_LEVEL. Toutefois, si Délai d’expiration = NULL ou *Délai d’attente != 0, l’appelant doit s’exécuter à IRQL <= APC_LEVEL et dans un contexte de thread nonarbitrary. (Si délai d’expiration != NULL et *Délai d’attente = 0, l’appelant doit s’exécuter à IRQL <= DISPATCH_LEVEL.)

Configuration requise

Condition requise Valeur
Client minimal pris en charge Disponible à partir de Windows 2000.
Plateforme cible Universal
En-tête wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
Bibliothèque NtosKrnl.lib
DLL NtosKrnl.exe
IRQL Consultez la section Notes.
Règles de conformité DDI HwStorPortProhibitedDDIs(storport), IrpProcessingComplete(wdm),IrqlKeWaitForMultipleObjects(wdm), SpNoWait(storport)

Voir aussi

ExInitializeFastMutex

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForSingleObject