Función KeWaitForMultipleObjects (wdm.h)
El KeWaitForMultipleObjects rutina coloca el subproceso actual en un estado de espera de alerta o no actualizable hasta que cualquiera o todos los objetos de distribuidor se establecen en un estado señalado o (opcionalmente) hasta que se agote el tiempo de espera.
Sintaxis
NTSTATUS
KeWaitForMultipleObjects (
ULONG Count,
PVOID Object[],
WaitType,
KWAIT_REASON WaitReason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout,
PKWAIT_BLOCK WaitBlockArray
);
Parámetros
[in] Count
Número de objetos en los que se va a esperar. Este parámetro especifica el número de elementos de la matriz a los que apunta el parámetro Object de.
[in] Object
Puntero a una matriz de punteros a objetos distribuidores (eventos, exclusión mutua, semáforos, subprocesos y temporizadores) para los que el autor de la llamada proporciona el almacenamiento. Tanto la matriz de punteros como los objetos de distribuidor deben residir en la memoria del sistema no paginada. Para obtener más información, vea Comentarios.
[in] WaitType
Tipo de operación de espera que se va a realizar. Especifique WaitAll, que indica que todos los objetos especificados deben alcanzar un estado señalado antes de que se cumpla la espera; o WaitAny, lo que indica que cualquiera de los objetos debe alcanzar un estado señalado antes de que se cumpla la espera.
[in] WaitReason
Motivo de la espera. Los controladores deben establecer este valor en executive o, si el controlador está trabajando en nombre de un usuario y se ejecuta en el contexto de un subproceso de usuario, para UserRequest.
[in] WaitMode
Indica si el autor de la llamada espera en kernelMode o UserMode. Los controladores intermedios y de nivel inferior deben especificar kernelMode. Si el conjunto de objetos esperados incluye una exclusión mutua, el autor de la llamada debe especificar KernelMode.
[in] Alertable
Valor booleano que indica si el subproceso se puede alertar mientras está en estado de espera.
[in, optional] Timeout
Puntero a un valor de tiempo de espera que especifica el tiempo absoluto o relativo, en unidades de 100 nanosegundos, en las que se va a completar la espera.
Un valor positivo especifica una hora absoluta, relativa al 1 de enero de 1601. Un valor negativo especifica un intervalo relativo a la hora actual. Los tiempos de expiración absolutos realizan un seguimiento de los cambios en la hora del sistema; Los tiempos de expiración relativos no se ven afectados por los cambios en la hora del sistema.
Si *tiempo de espera = 0, la rutina devuelve sin esperar. Si el autor de la llamada proporciona un puntero de NULL, la rutina espera indefinidamente hasta que cualquiera o todos los objetos del distribuidor se establecen en el estado señalado. Para obtener más información, vea la siguiente sección Comentarios.
[out, optional] WaitBlockArray
Puntero a una matriz de KWAIT_BLOCK asignada por el autor de la llamada. Si Count<= THREAD_WAIT_OBJECTS, waitBlockArray puede ser NULL. De lo contrario, este parámetro debe apuntar a un búfer de memoria de tamaño de(KWAIT_BLOCK) * Count bytes. La rutina usa este búfer para el mantenimiento de registros mientras realiza la operación de espera. El waitBlockArray búfer debe residir en la memoria del sistema no paginada. Para obtener más información, vea Comentarios.
Valor devuelto
keWaitForMultipleObjects puede devolver una de las siguientes opciones:
Código devuelto | Descripción |
---|---|
STATUS_SUCCESS | El autor de la llamada especificó WaitAll para el parámetro WaitType y todos los objetos distribuidores de la matriz Object se han establecido en el estado señalado. |
STATUS_ALERTED | La espera se interrumpió para entregar una alerta al subproceso de llamada. |
STATUS_USER_APC | La espera se interrumpió para entregar una llamada de procedimiento asincrónico del usuario (APC) al subproceso que realiza la llamada. |
STATUS_TIMEOUT | Se agotó el tiempo de espera antes de que se cumpla el conjunto especificado de condiciones de espera. Este valor se puede devolver cuando se especifica un valor de tiempo de espera explícito de cero, pero no se puede cumplir inmediatamente el conjunto especificado de condiciones de espera. |
STATUS_WAIT_0 a través de STATUS_WAIT_63 | El autor de la llamada especificó WaitAny para WaitType y uno de los objetos distribuidores de la matriz Object se ha establecido en el estado señalado. Los seis bits inferiores del valor devuelto codifican el índice de base cero del objeto que satisface la espera. |
STATUS_ABANDONED_WAIT_0 a través de STATUS_ABANDONED_WAIT_63 | El autor de la llamada intentó esperar una exclusión mutua que se ha abandonado. Los seis bits inferiores del valor devuelto codifican el índice de base cero de la exclusión mutua en la matriz Object. |
Tenga en cuenta que la macro NT_SUCCESS reconoce todos estos valores de estado como valores "correctos".
Observaciones
Cada objeto de subproceso tiene una matriz integrada de bloques de espera que se pueden usar para esperar a que varios objetos se establezcan simultáneamente. Siempre que sea posible, la matriz integrada de bloques de espera debe usarse en una operación wait-multiple porque no es necesario asignar ningún almacenamiento de bloque de espera adicional y desasignarse posteriormente. Sin embargo, si el número de objetos que se deben esperar simultáneamente es mayor que el número de bloques de espera integrados, use el parámetro WaitBlockArray para especificar un conjunto alternativo de bloques de espera que se usarán en la operación de espera. Los controladores solo necesitan asignar un búfer de memoria suficientemente grande para WaitBlockArray. No es necesario inicializar el búfer; sin embargo, debe asignarse a partir de la memoria del sistema no paginada. Si el parámetro WaitMode es UserMode, el búfer de WaitBlockArray no debe asignarse en la pila local porque la pila podría intercambiarse sin memoria. Los controladores pueden tratar este búfer como una estructura opaca y pueden liberarlo después de que la rutina vuelva. Si > MAXIMUM_WAIT_OBJECTS Count o si WaitBlockArray es NULL y Count> THREAD_WAIT_OBJECTS, el sistema emite 0xC de comprobación de errores (MAXIMUM_WAIT_OBJECTS_EXCEEDED).
El estado actual de cada uno de los objetos especificados se examina para determinar si la espera se puede satisfacer inmediatamente. Si se realizan los efectos secundarios necesarios en los objetos , se devuelve un valor adecuado.
Si no se puede satisfacer la espera inmediatamente y no se ha especificado ningún valor de tiempo de espera o un valor de tiempo de espera distinto de cero, el subproceso actual se coloca en un estado de espera y se selecciona un nuevo subproceso para su ejecución en el procesador actual. Si no se proporciona ningún de tiempo de espera, el subproceso de llamada permanecerá en un estado de espera hasta que se cumplan las condiciones especificadas por Object y WaitType.
Si se especifica de tiempo de espera, la espera se cumplirá automáticamente si no se cumple ninguna de las condiciones de espera especificadas cuando expire el intervalo especificado.
Un valor de tiempo de espera de cero permite realizar las pruebas de un conjunto de condiciones de espera, realizando condicionalmente los efectos secundarios si la espera se puede satisfacer inmediatamente, como en la adquisición de una exclusión mutua.
Los intervalos de tiempo de espera se miden en relación con el reloj del sistema y la precisión con la que el sistema operativo puede detectar el final de un intervalo de tiempo de espera está limitado por la granularidad del reloj del sistema. Para obtener más información, vea Precisión del temporizador.
El parámetro Alertable determina cuándo se puede alertar al subproceso y su estado de espera, por lo tanto, anulado. Para obtener más información, consulte esperas y API.
La matriz a la que apunta el parámetro Objects debe residir en la memoria del sistema no paginada. Normalmente, un controlador asigna el almacenamiento de Objetos matriz en la pila local. La matriz Objects se puede asignar en la pila local independientemente del valor del parámetro WaitMode.
Los objetos distribuidores a los que apuntan los elementos del Objetos matriz deben residir en memoria del sistema no paginada. Si el parámetro WaitMode es UserMode, la pila del kernel se puede intercambiar durante la espera. Por lo tanto, un autor de llamada nunca debe intentar pasar parámetros en la pila al llamar a KeWaitForMultipleObjects con el argumento UserMode. Si asigna el evento en la pila, debe establecer el parámetro WaitMode en KernelMode.
Se aplica una consideración especial cuando el parámetro Object pasado a KeWaitForMultipleObjects es una exclusión mutua. Si el objeto distribuidor en el que se espera es una exclusión mutua, la entrega de APC es la misma que para todos los demás objetos del distribuidor durante la espera. Sin embargo, después de KeWaitForMultipleObjects devuelve con STATUS_SUCCESS y el subproceso contiene realmente la exclusión mutua, solo se entregan las API en modo kernel especiales. La entrega de todas las demás API, tanto en modo kernel como en modo de usuario, está deshabilitada. Esta restricción en la entrega de LAS API persiste hasta que se libera la exclusión mutua.
Es especialmente importante comprobar el valor devuelto de KeWaitForMultipleObjects cuando el parámetro WaitMode es UserMode o Alertable es TRUE, ya que KeWaitForMultipleObjects puede devolver temprano con un estado de STATUS_USER_APC o STATUS_ALERTED.
Todas las esperas a largo plazo que un usuario puede anular deben esperas de userMode y alertables deben establecerse en FALSE.
Siempre que sea posible, alertable debe establecerse en FALSE y WaitMode debe establecerse en KernelMode, con el fin de reducir la complejidad del controlador. La excepción principal a esto es cuando la espera es una espera a largo plazo.
Una exclusión mutua solo se puede adquirir de forma recursiva solo las veces de MINLONG. Si se supera este límite, la rutina genera una excepción de STATUS_MUTANT_LIMIT_EXCEEDED.
Los autores de llamadas de KeWaitForMultipleObjects se pueden ejecutar en IRQL <= DISPATCH_LEVEL. Sin embargo, si tiempo de espera = NULL o *tiempo de espera != 0, el autor de la llamada debe ejecutarse en IRQL <= APC_LEVEL y en un contexto de subproceso nobitrario. (Si tiempo de espera != NULL y *tiempo de espera = 0, el autor de la llamada debe ejecutarse en IRQL <= DISPATCH_LEVEL).)
Requisitos
Requisito | Valor |
---|---|
cliente mínimo admitido | Disponible a partir de Windows 2000. |
de la plataforma de destino de | Universal |
encabezado de | wdm.h (include Wdm.h, Ntddk.h, Ntifs.h) |
biblioteca de | NtosKrnl.lib |
DLL de | NtosKrnl.exe |
irQL | Consulte la sección Comentarios. |
reglas de cumplimiento de DDI | HwStorPortProhibitedDIs(storport), IrpProcessingComplete(wdm), IrqlKeWaitForMultipleObjects(wdm), SpNoWait(storport) |