Función WdfInterruptTryToAcquireLock (wdfinterrupt.h)
[Se aplica a KMDF y UMDF]
El método WdfInterruptTryToAcquireLock intenta adquirir el bloqueo pasivo de un objeto de interrupción.
Sintaxis
BOOLEAN WdfInterruptTryToAcquireLock(
[in] WDFINTERRUPT Interrupt
);
Parámetros
[in] Interrupt
Identificador de un objeto de interrupción de marco.
Valor devuelto
WdfInterruptTryToAcquireLock devuelve TRUE si adquiere correctamente el bloqueo de la interrupción. En caso contrario, el método devuelve FALSE.
Comentarios
Los controladores que usan el control de interrupciones de nivel pasivo llaman a WdfInterruptTryToAcquireLock para iniciar una secuencia de código que se ejecuta en IRQL = PASSIVE_LEVEL mientras mantiene el bloqueo de interrupción de nivel pasivo que el controlador configuró en la estructura de WDF_INTERRUPT_CONFIG del objeto de interrupción.
WdfInterruptTryToAcquireLock intenta adquirir el bloqueo y, a continuación, devuelve inmediatamente, si ha adquirido el bloqueo o no. Si WdfInterruptTryToAcquireLock adquiere correctamente el bloqueo, el marco llama a KeEnterCriticalRegion antes de devolver para que se deshabiliten las API normales del kernel.
En el caso de los objetos de interrupción de nivel pasivo, los controladores deben llamar a WdfInterruptTryToAcquireLock en lugar de WdfInterruptAcquireLock, al ejecutarse en un subproceso arbitrario, como una función de devolución de llamada de objeto de cola. Por ejemplo, el controlador podría llamar a WdfInterruptTryToAcquireLock desde EvtIoRead. Esto evita la posibilidad de interbloqueo, como se describe en la sección Comentarios de WdfInterruptAcquireLock.
Cuando se ejecuta en un subproceso no arbitrario, como un elemento de trabajo, el controlador debe usar WdfInterruptAcquireLock.
Cuando el controlador llama a WdfInterruptReleaseLock, el marco libera el bloqueo de interrupción.
Ejemplos
En el ejemplo de código siguiente se muestra cómo una función de devolución de llamada EvtIoRead , que se ejecuta en un contexto arbitrario, podría llamar a WdfInterruptTryToAcquireLock antes de realizar el trabajo relacionado con interrupciones. Si el método devuelve FALSE, el controlador pone en cola un elemento de trabajo para realizar el trabajo en un subproceso no arbitrario. El controlador también proporciona una función de devolución de llamada EvtWorkItem que llama a WdfInterruptAcquireLock antes de realizar el trabajo.
En este ejemplo, el controlador ha especificado la distribución secuencial para la cola. Si el controlador especificó cualquier otro método de distribución para la cola, el controlador debe usar una cola manual adicional para conservar las solicitudes de procesamiento en el elemento de trabajo. Los comentarios de código describen dónde agregar dicha compatibilidad.
VOID EvtIoRead(
__in WDFQUEUE Queue,
__in WDFREQUEST Request,
__in size_t Length
)
{
DEVICE_CONTEXT devCtx;
devCtx = GetDeviceContext(WdfIoQueueGetDevice(Queue));
//
// Do any pre-acquiring interrupt lock work here.
//
//
// Check if we can acquire the lock.
//
if (WdfInterruptTryToAcquireLock(devCtx->InterruptObject) {
ReadFunctionLocked(Request);
WdfInterruptReleaseLock(devCtx->InterruptObject);
//
// Do any post-releasing interrupt lock work here.
// For example: complete the request, and so on.
//
ReadFunctionFinish(Request);
}
else {
WORK_ITEM_CONTEXT ctx;
ctx = GetWorkItemContext(ReadWorkItem);
ctx->Request = Request;
// If previous queue is non-sequential, call WdfRequestForwardToIoQueue
// to store request in an additional manual queue.
WdfWorkItemEnqueue(ReadWorkItem);
}
}
VOID
EvtReadWorkItemCallback(
WDFWORKITEM WorkItem
)
{
WORK_ITEM_CONTEXT wiCtx;
DEVICE_CONTEXT devCtx;
wiCtx = GetWorkItemContext(ReadWorkItem);
devCtx = GetDeviceContext(WdfWorkItemGetParentObject(WorkItem));
// If delivery queue is non-sequential, call WdfIoQueueRetrieveNextRequest
// to retrieve request that we stored in EvtIoRead.
//
// Acquire interrupt lock.
//
WdfInterruptAcquireLock(devCtx->InterruptObject);
ReadFunctionLocked(wiCtx->Request);
WdfInterruptReleaseLock(devCtx->InterruptObject);
//
// Do any post-releasing interrupt lock work here.
// For example: complete the request, and so on.
//
ReadFunctionFinish(wiCtx->Request);
}
Requisitos
Requisito | Value |
---|---|
Plataforma de destino | Universal |
Versión mínima de KMDF | 1.11 |
Versión mínima de UMDF | 2.0 |
Encabezado | wdfinterrupt.h (incluir Wdf.h) |
Library | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | PASSIVE_LEVEL |
Reglas de cumplimiento de DDI | DriverCreate(kmdf) |