Función KeWaitForSingleObject (wdm.h)
La rutina KeWaitForSingleObject coloca el subproceso actual en un estado de espera hasta que el objeto distribuidor especificado esté establecido en un estado señalado o (opcionalmente) hasta que se agote el tiempo de espera.
Sintaxis
NTSTATUS
KeWaitForSingleObject (
PVOID Object,
KWAIT_REASON WaitReason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout
);
Parámetros
[in] Object
Puntero a un objeto de distribuidor inicializado (evento, exclusión mutua, semáforo, subproceso o temporizador) para el que el autor de la llamada proporciona el almacenamiento. El objeto distribuidor debe residir en la memoria del sistema no paginada. Para obtener más información, vea la sección Comentarios.
[in] WaitReason
Especifica el motivo de la espera. Un controlador debe establecer este valor en Executive, a menos que esté trabajando en nombre de un usuario y se ejecute en el contexto de un subproceso de usuario, en cuyo caso debe establecer este valor en UserRequest.
[in] WaitMode
Especifica si el autor de la llamada espera en KernelMode o UserMode. Los controladores intermedios y de nivel más bajo deben especificar KernelMode. Si el objeto especificado es una exclusión mutua, el autor de la llamada debe especificar KernelMode.
[in] Alertable
Especifica un valor booleano que es TRUE si la espera es alertable y FALSE en caso contrario.
[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 de hora del sistema.
Si Timeout = 0, la rutina vuelve sin esperar. Si el autor de la llamada proporciona un puntero NULL , la rutina espera indefinidamente hasta que el objeto distribuidor se establece en el estado señalado. Para obtener más información, vea la sección Comentarios que se muestra más adelante.
Valor devuelto
KeWaitForSingleObject puede devolver una de las siguientes opciones.
La macro NT_SUCCESS reconoce todos estos valores de estado como valores "correctos".
Código devuelto | Descripción |
---|---|
STATUS_SUCCESS | El objeto distribuidor especificado por el parámetro Object cumplió la espera. |
STATUS_ALERTED | La espera se interrumpió para entregar una alerta al subproceso que llama. |
STATUS_USER_APC | La espera se interrumpió para entregar una llamada de procedimiento asincrónico de usuario (APC) al subproceso que llama. |
STATUS_TIMEOUT | Se ha agotado el tiempo de espera antes de establecer el objeto en un estado señalado. Este valor se puede devolver cuando no se puede cumplir inmediatamente el conjunto especificado de condiciones de espera y Timeout se establece en cero. |
Comentarios
El estado actual del objeto especificado se examina para determinar si la espera se puede satisfacer inmediatamente. Si es así, los efectos secundarios necesarios se realizan en el objeto . De lo contrario, el subproceso actual se coloca en un estado de espera y se selecciona un nuevo subproceso para su ejecución en el procesador actual.
El parámetro Alertable determina cuándo se puede alertar al subproceso y su estado de espera, en consecuencia, anulado. Para obtener más información, consulte Esperas y API.
Se aplica una consideración especial cuando el parámetro Object pasado a KeWaitForSingleObject es una exclusión mutua. Si el objeto dispatcher esperado es una exclusión mutua, la entrega de APC es la misma que para todos los demás objetos de distribuidor durante la espera. Sin embargo, después de que KeWaitForSingleObject vuelva con STATUS_SUCCESS y el subproceso contiene realmente la exclusión mutua, solo se entregan las API especiales en modo kernel. La entrega de todas las demás API, tanto en modo kernel como en modo usuario, está deshabilitada. Esta restricción en la entrega de APCs persiste hasta que se libera la exclusión mutua.
El objeto distribuidor al que apunta el parámetro Object debe residir en la 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 llamador nunca debe intentar pasar parámetros en la pila al llamar a KeWaitForSingleObject mediante el argumento UserMode . Si asigna el evento en la pila, debe establecer el parámetro WaitMode en KernelMode.
Es especialmente importante comprobar el valor devuelto de KeWaitForSingleObject cuando el parámetro WaitMode es UserMode o Alertable es TRUE, ya que KeWaitForSingleObject 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 ser esperas UserMode y Alertable debe establecerse en FALSE.
Siempre que sea posible, Alertable debe establecerse en FALSE y WaitMode debe establecerse en KernelMode para reducir la complejidad del controlador. La excepción principal a esto es cuando la espera es una espera a largo plazo.
Si se proporciona un puntero NULL para Timeout, el subproceso de llamada permanece en un estado de espera hasta que se señala el objeto .
Un valor de tiempo de espera de cero permite probar un conjunto de condiciones de espera y para el rendimiento condicional de cualquier efecto secundario si la espera puede cumplirse 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.
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 KeWaitForSingleObject deben ejecutarse en IRQL <= DISPATCH_LEVEL. Sin embargo, si Timeout = NULL o Timeout != 0, el autor de la llamada debe ejecutarse en IRQL <= APC_LEVEL y en un contexto de subproceso nobitrario. Si Timeout != NULL y Timeout = 0, el autor de la llamada debe ejecutarse en IRQL <= DISPATCH_LEVEL.
KeWaitForMutexObject es una macro que se convierte en KeWaitForSingleObject, que se puede usar en su lugar.
Para mejorar el rendimiento, use exclusión mutua rápida o exclusión mutua protegida. Para obtener más información, vea Alternativas a objetos de exclusión mutua.
Para obtener más información sobre los objetos de exclusión mutua, vea Objetos de exclusión mutua.