Partager via


KeWaitForMultipleObjects, fonction (wdm.h)

La routine KeWaitForMultipleObjects place le thread actuel dans un état d’attente alertable ou non modifiable jusqu’à ce que l’un ou l’ensemble des 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é par 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 paginé. Pour plus d’informations, consultez Remarques.

[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

Raison de l’attente. Les pilotes doivent définir cette valeur sur Exécutif ou, si le pilote effectue un travail au nom d’un utilisateur et s’exécute dans le contexte d’un thread d’utilisateur, pour UserRequest.

[in] WaitMode

Indique si l’appelant attend 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é pendant qu’il est dans l’état d’attente.

[in, optional] Timeout

Pointeur vers une valeur de délai d’attente qui spécifie le temps absolu ou relatif, 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 modifications de temps 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 Remarques suivante.

[out, optional] WaitBlockArray

Pointeur vers un tableau KWAIT_BLOCK alloué par l’appelant. Si count<= THREAD_WAIT_OBJECTS, WaitBlockArray peut être NULL. Sinon, ce paramètre doit pointer vers une mémoire tampon de taille de(KWAIT_BLOCK) * Count 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 paginé. Pour plus d’informations, consultez Remarques.

Valeur de retour

KeWaitForMultipleObjects pouvez retourner l’une des options suivantes :

Retourner le code Description
STATUS_SUCCESS L’appelant spécifié WaitAll pour le paramètre WaitType et tous les objets de répartiteur du tableau Object 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 spécifié de conditions d’attente 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 spécifié de conditions d’attente ne peut pas être rempli immédiatement.
STATUS_WAIT_0 via STATUS_WAIT_63 L’appelant spécifié WaitAny pour WaitType et l’un des objets de répartiteur dans le tableau Object a été défini sur l’état signalé. Six bits inférieurs de la valeur de retour encodent l’index de base zéro de l’objet qui satisfait l’attente.
STATUS_ABANDONED_WAIT_0 via STATUS_ABANDONED_WAIT_63 L’appelant a tenté d’attendre un mutex abandonné. 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 d’état comme des valeurs de « réussite ».

Remarques

Chaque objet thread a un tableau intégré de blocs d’attente qui peuvent être utilisés 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 n’a besoin d’ê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 volumineuse pour WaitBlockArray. La mémoire tampon n’a pas besoin d’être initialisée ; toutefois, elle doit être allouée à partir de la mémoire système non paginé. 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. Les pilotes peuvent traiter cette mémoire tampon comme une structure opaque et la libérer une fois la routine retournée. Si count> MAXIMUM_WAIT_OBJECTS ou si WaitBlockArray est NULL et Count> THREAD_WAIT_OBJECTS, les problèmes système 0xC (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 aucune 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’expiration 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 satisfaites.

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

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

Les intervalles de délai d’attente 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’attente 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 a donc été abandonné. Pour plus d’informations, consultez Attente et API.

Le tableau pointé par le paramètre Objects doit résider dans la mémoire système non paginé. En règle générale, un pilote alloue le stockage pour le tableau Objects 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 Objects doivent résider dans la mémoire système non paginé. 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 transmettre 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 d’APC est la même que pour tous les autres objets de répartiteur pendant l’attente. Toutefois, après KeWaitForMultipleObjects retourne avec STATUS_SUCCESS et le thread contient réellement le mutex, seules les API en mode noyau spécial sont remises. La remise de toutes 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 vérifier la valeur de retour de KeWaitForMultipleObjects lorsque le paramètre WaitMode est UserMode ou Alertable est TRUE, car KeWaitForMultipleObjects peut retourner tôt avec un état de STATUS_USER_APC ou de STATUS_ALERTED.

Toutes les attentes à long terme qui peuvent être abandonnées par un utilisateur doivent être 'attente userMode et alertable doit être définie sur FALSE.

Dans la mesure du possible, alertable doit être défini sur FALSE et WaitMode doit être défini sur KernelMode, afin de réduire la complexité du pilote. L’exception principale à ceci est lorsque l’attente est une attente à long terme.

Un mutex peut être acquis de manière récursive uniquement à des heures 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 à l'<IRQL = DISPATCH_LEVEL. Toutefois, si délai d’expiration = NULL ou *délai d’expiration != 0, l’appelant doit s’exécuter à IRQL <= APC_LEVEL et dans un contexte de thread nonarbitraire. (Si délai d’expiration != NULL et *délai d’expiration = 0, l’appelant doit s’exécuter à IRQL <= DISPATCH_LEVEL.)

Exigences

Exigence Valeur
client minimum pris en charge Disponible à partir de Windows 2000.
plateforme cible Universel
d’en-tête wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
bibliothèque NtosKrnl.lib
DLL NtosKrnl.exe
IRQL Voir la section Remarques.
règles de conformité DDI HwStorPortProhibitedDDIs(storport), IrpProcessingComplete(wdm), IrqlKeWaitForMultipleObjects(wdm), SpNoWait(storport)

Voir aussi

ExInitializeFastMutex

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForSingleObject