Fonction KeWaitForSingleObject (wdm.h)
La routine KeWaitForSingleObject place le thread actuel dans un état d’attente jusqu’à ce que l’objet de répartiteur donné soit défini sur un état signalé ou (éventuellement) jusqu’à ce que l’attente expire.
Syntaxe
NTSTATUS
KeWaitForSingleObject (
PVOID Object,
KWAIT_REASON WaitReason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout
);
Paramètres
[in] Object
Pointeur vers un objet de répartiteur initialisé (événement, mutex, sémaphore, thread ou minuteur) pour lequel l’appelant fournit le stockage. L’objet dispatcher doit résider dans la mémoire système non pagée. Pour plus d'informations, consultez la section Notes.
[in] WaitReason
Spécifie la raison de l’attente. Un pilote doit définir cette valeur sur Executive, sauf s’il effectue un travail pour le compte d’un utilisateur et s’exécute dans le contexte d’un thread utilisateur, auquel cas il doit définir cette valeur sur UserRequest.
[in] WaitMode
Spécifie si l’appelant attend dans KernelMode ou UserMode. Les pilotes de niveau le plus bas et intermédiaire doivent spécifier KernelMode. Si l’objet donné est un mutex, l’appelant doit spécifier KernelMode.
[in] Alertable
Spécifie une valeur booléenne qui est TRUE si l’attente est alertable et FALSE dans le cas contraire.
[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 l’objet répartiteur soit défini à l’état signalé. Pour plus d'informations, consultez la section Notes qui suit.
Valeur retournée
KeWaitForSingleObject peut retourner l’un des éléments suivants.
La macro NT_SUCCESS reconnaît toutes ces valeurs status comme des valeurs de « réussite ».
Code de retour | Description |
---|---|
STATUS_SUCCESS | L’objet de répartiteur spécifié par le paramètre Object a satisfait à l’attente. |
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’objet soit défini sur un état signalé. Cette valeur peut être retournée lorsque l’ensemble de conditions d’attente spécifié ne peut pas être immédiatement rempli et que le délai d’expiration est défini sur zéro. |
Remarques
L’état actuel de l’objet spécifié est examiné pour déterminer si l’attente peut être satisfaite immédiatement. Si c’est le cas, les effets secondaires nécessaires sont effectués sur l’objet. Sinon, 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.
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.
Une considération particulière s’applique lorsque le paramètre Object passé à KeWaitForSingleObject 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 KeWaitForSingleObject est retourné avec STATUS_SUCCESS et que le thread contient réellement le mutex, seuls les API en mode noyau spéciaux sont remises. 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é.
L’objet dispatcher pointé vers le paramètre Object doit 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 KeWaitForSingleObject à l’aide de l’argument UserMode . Si vous allouez l’événement sur la pile, vous devez définir le paramètre WaitMode sur KernelMode.
Il est particulièrement important de case activée la valeur de retour de KeWaitForSingleObject lorsque le paramètre WaitMode est UserMode ou alertable a la valeur TRUE, car KeWaitForSingleObject 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.
Si un pointeur NULL est fourni pour le délai d’expiration, le thread appelant reste dans un état d’attente jusqu’à ce que l’objet soit signalé.
Une valeur de délai d’attente égale à zéro permet de tester un ensemble de conditions d’attente et d’obtenir les performances conditionnelles des effets secondaires si l’attente peut être satisfaite immédiatement, 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.
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 KeWaitForSingleObject doivent être en cours d’exécution sur 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 non linéaire. Si Délai d’expiration != NULL et Délai d’expiration = 0, l’appelant doit s’exécuter à IRQL <= DISPATCH_LEVEL.
KeWaitForMutexObject est une macro qui se convertit en KeWaitForSingleObject, qui peut être utilisée à la place.
Pour de meilleures performances, utilisez des mutex rapides ou des mutex surveillés. Pour plus d’informations, consultez Alternatives aux objets Mutex.
Pour plus d’informations sur les objets mutex, consultez Objets Mutex.
Configuration requise
Condition requise | Valeur |
---|---|
Plateforme cible | Universal |
En-tête | wdm.h (inclure Wdm.h, Ntddk.h, Ntifs.h) |
Bibliothèque | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | Consultez la section Notes. |
Règles de conformité DDI | CompleteRequestStatusCheck(wdm),HwStorPortProhibitedDDIs(storport),IoAllocateIrpSignalEventInCompletionTimeout(wdm), IoBuildDeviceControlWait(wdm),IoBuildDeviceControlWaitTimeout(wdm), IoBuildFsdIrpSignalEventInCompletionTimeout(wdm),IoBuildSynchronousFsdRequestWait(wdm),IoBuildSynchronousFsdRequestWaitTimeout(wdm), IrpProcessingComplete(wdm), IrqlKeWaitForMutexObject(wdm), LowerDriverReturn(wdm), MarkIrpPending2(wdm), PendedCompletedRequest(wdm), PendedCompletedRequest2(wdm), PendedCompletedRequest3(wdm), PendedCompletedRequestEx(wdm), RemoveLockForwardDeviceControl(wdm), RemoveLockForwardDeviceControlInternal(wdm), RemoveLockForwardRead(wdm), RemoveLockForwardWrite(wdm), SpNoWait(storport),StartDeviceWait(wdm), StartDeviceWait2(wdm), StartDeviceWait3(wdm), StartDeviceWait4(wdm) |