Compartir a través de


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)

Consulte también

EvtInterruptWorkItem

WDF_INTERRUPT_CONFIG

WdfInterruptAcquireLock

WdfInterruptReleaseLock

WdfIoQueueRetrieveNextRequest

WdfRequestRequeue

WdfWaitLockAcquire