Partager via


FsRtlCancellableWaitForMultipleObjects, fonction (ntifs.h)

La routine FsRtlCancellableWaitForMultipleObjects exécute une opération d’attente annulable (une attente qui peut être terminée) sur un ou plusieurs objets de répartiteur.

Syntaxe

NTSTATUS FsRtlCancellableWaitForMultipleObjects(
  [in]           ULONG          Count,
  [in]           PVOID []       ObjectArray,
  [in]           WAIT_TYPE      WaitType,
  [in, optional] PLARGE_INTEGER Timeout,
  [in, optional] PKWAIT_BLOCK   WaitBlockArray,
  [in, optional] PIRP           Irp
);

Paramètres

[in] Count

Nombre d’objets à attendre.

[in] ObjectArray

Pointeur vers un tableau de pointeurs vers des objets de répartiteur (événements, mutex, sémaphores, threads et minuteurs) pour lesquels l’appelant fournit le stockage.

[in] WaitType

Soit WaitAll, qui indique que tous les objets spécifiés doivent atteindre un état signalé avant que l’attente soit satisfaite ; ou WaitAny, qui indique que l’un des objets doit atteindre un état signalé avant que l’attente soit satisfaite.

[in, optional] Timeout

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

Si le délai d’expiration pointe vers une valeur zéro (autrement dit, *Délai d’attente == 0), la routine retourne sans attendre. Si l’appelant fournit un pointeur NULL (autrement dit, Timeout == NULL), la routine attend indéfiniment jusqu’à ce que tous les objets de répartiteur soient définis sur l’état signalé.

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 temps d’expiration absolus suivent les modifications apportées à l’heure système ; les temps d’expiration relatifs ne sont pas affectés par les changements d’heure système.

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 (autrement dit, *Délai d’attente == 0) vous permet de tester un ensemble de conditions d’attente et d’effectuer de manière conditionnelle toutes les actions supplémentaires si l’attente peut être satisfaite immédiatement, comme lors de l’acquisition d’un mutex.

[in, optional] WaitBlockArray

Si Count<= THREAD_WAIT_OBJECTS, WaitBlockArray peut avoir la valeur NULL. Sinon, ce paramètre doit pointer vers une mémoire tampon d’octets sizeof(KWAIT_BLOCK * Count) . La routine utilise cette mémoire tampon pour la conservation des enregistrements lors de l’exécution de l’opération d’attente.

[in, optional] Irp

Pointeur vers l’IRP d’origine qui correspond à l’opération d’E/S qui a été émise par l’utilisateur et qui peut être annulée par l’utilisateur. L’appelant doit s’assurer que l’IRP reste valide pendant la durée de cette routine et que l’IRP ne doit pas avoir de routine d’annulation définie (par exemple, IoSetCancelRoutine ne doit pas avoir été appelé sur l’IRP). Notez que l’IRP doit être détenu par l’appelant. Il ne peut pas être passé à un pilote de niveau inférieur.

Valeur retournée

FsRtlCancellableWaitForMultipleObjects peut retourner l’une des valeurs suivantes :

Code de retour Description
STATUS_SUCCESS L’appelant a spécifié WaitAll pour le paramètre WaitType et tous les objets répartiteurs dans le tableau ObjectArray ont été définis sur l’état signalé.
STATUS_TIMEOUT Un délai d’attente s’est produit avant que le jeu de conditions d’attente spécifié soit rempli. Cette valeur peut être retournée lorsque le jeu 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.
STATUS_WAIT_0 à STATUS_WAIT_63 L’appelant a spécifié WaitAny pour WaitType et l’un des objets de répartiteur dans le tableau ObjectArray 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 à 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 ObjectArray .
STATUS_CANCELLED L’attente a été interrompue par une demande d’annulation en attente sur l’IRP spécifié. Notez que cette valeur est retournée uniquement si un IRP valide est passé à FsRtlCancellableWaitForMultipleObjects et si l’IRP a été annulé par CancelSynchronousIo.
STATUS_THREAD_IS_TERMINATING L’attente a été interrompue, car le thread a été arrêté par une application ou l’utilisateur.

La valeur de retour indique uniquement la status de l’attente. Le cas échéant, la status réelle de la demande d’E/S doit être obtenue directement à partir d’un autre IRP généré dans le processus de gestion de l’IRP en mode utilisateur d’origine.

Notez que la macro NT_SUCCESS retourne FALSE (« failure ») pour les valeurs STATUS_CANCELLED et STATUS_THREAD_IS_TERMINATING status et TRUE (« success ») pour toutes les autres valeurs status.

Remarques

La routine FsRtlCancellableWaitForMultipleObjects exécute une opération d’attente annulable sur les objets de répartiteur. Si le thread est arrêté par l’utilisateur ou par l’application, ou si CancelSynchronousIo publie une demande d’annulation sur un IRP (IRP synchrone) threadé associé au thread, l’attente est annulée.

La routine FsRtlCancellableWaitForMultipleObjects a été conçue pour prendre en charge les instructions d’achèvement/annulation d’E/ S à partir de Windows Vista. L’objectif de ces instructions est de permettre aux utilisateurs (ou aux applications) d’arrêter rapidement les applications. Cela nécessite que les applications aient la possibilité d’arrêter rapidement les threads qui exécutent des E/S, ainsi que toutes les opérations d’E/S actuelles. Cette routine permet aux threads utilisateur de bloquer (c’est-à-dire d’attendre) dans le noyau l’achèvement des E/S, les objets de répartiteur ou les variables de synchronisation d’une manière qui permet d’annuler facilement l’attente. Cette routine permet également d’arrêter l’attente du thread si le thread est arrêté par un utilisateur ou une application.

Par exemple, un redirecteur peut avoir besoin de créer un ou plusieurs IRP secondaires pour traiter un IRP en mode utilisateur et attendre de façon synchrone que les IRP secondaires se terminent. Une façon de procéder consiste à configurer un événement qui sera signalé par la routine d’achèvement de l’IRP secondaire, puis à attendre que l’événement soit signalé. Ensuite, pour effectuer une opération d’attente annulable, FsRtlCancellableWaitForMultipleObjects est appelé en passant dans l’événement associé à l’IRP secondaire, ainsi que l’IRP en mode utilisateur d’origine. L’attente du thread pour que l’événement soit signalé est annulée si un événement d’arrêt en attente se produit ou si l’IRP en mode utilisateur d’origine est annulé.

Notez que la fin de l’attente n’annule pas automatiquement les opérations d’E/S émises par l’appelant, qui doivent être gérées séparément par l’appelant.

Chaque objet thread a un tableau intégré de blocs d’attente qui peut être utilisé pour attendre simultanément sur plusieurs objets. 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é, puis 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 grande pour WaitBlockArray. La mémoire tampon n’a pas besoin d’être initialisée et les pilotes peuvent la traiter comme une structure opaque. La mémoire tampon peut être libérée une fois que la routine est retournée.

Si Count est supérieur à MAXIMUM_WAIT_OBJECTS ou si WaitBlockArray a la valeur NULL et Count est supérieur à THREAD_WAIT_OBJECTS, le système émet la vérification des bogues 0xC : MAXIMUM_WAIT_OBJECTS_EXCEEDED.

Une considération particulière s’applique lorsque le paramètre ObjectArray passé à FsRtlCancellableWaitForMultipleObjects est un mutex. Si l’objet de répartiteur attendu est un mutex, la livraison APC est la même que pour tous les autres objets de répartiteur pendant l’attente. Toutefois, une fois que FsRtlCancellableWaitForMultipleObjects retourne avec STATUS_SUCCESS et que le thread contient réellement le mutex, seuls les API spéciaux en mode noyau sont remises. La remise de tous les autres API, à la fois 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é.

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.

FsRtlCancellableWaitForMultipleObjects doit être appelé au PASSIVE_LEVEL IRQL si le paramètre Irp facultatif pointe vers un IRP valide. Si le paramètre Irp n’est pas utilisé, la routine peut être appelée au niveau IRQL inférieur ou égal à APC_LEVEL. Les API du noyau normal peuvent être désactivées par l’appelant, si nécessaire, en appelant les routines KeEnterCriticalRegion ou FsRtlEnterFileSystem . Toutefois, les API de noyau spéciales ne doivent pas être désactivées.

FsRtlCancellableWaitForMultipleObjects s’affirme sur les builds de débogage si l’IRQL est supérieur ou égal à APC_LEVEL et que le paramètre Irp pointe vers un IRP valide.

Configuration requise

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

Voir aussi

ExInitializeFastMutex

FsRtlCancellableWaitForSingleObject

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject

KeWaitForMutexObject