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 del marco.
Valor devuelto
WdfInterruptTryToAcquireLock devuelve TRUE si adquiere correctamente el bloqueo de la interrupción. De lo contrario, el método devuelve FALSE.
Observaciones
Los controladores que usan 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, tanto si ha adquirido el bloqueo como si no. Si WdfInterruptTryToAcquireLock adquiere correctamente el bloqueo, el marco llama a KeEnterCriticalRegion antes de devolver para que las API de kernel normales estén deshabilitadas.
Para los objetos de interrupción de nivel pasivo, los controladores deben llamar a WdfInterruptTryToAcquireLock en lugar de WdfInterruptAcquireLock, cuando se ejecuta en un subproceso arbitrario, como una función de devolución de llamada de objeto de cola de . Por ejemplo, el controlador podría llamar a WdfInterruptTryToAcquireLock desde EvtIoRead. Al hacerlo, se 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 EvtIo Read, 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 un EvtWorkItem función de devolución de llamada que llama a WdfInterruptAcquireLock antes de realizar el trabajo.
En este ejemplo, el controlador ha especificado secuencial distribución de la cola. Si el controlador especificado 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 | Valor |
---|---|
de la plataforma de destino de | Universal |
versión mínima de KMDF | 1.11 |
versión mínima de UMDF | 2.0 |
encabezado | wdfinterrupt.h (incluya Wdf.h) |
Biblioteca | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
irQL | PASSIVE_LEVEL |
reglas de cumplimiento de DDI | DriverCreate(kmdf) |