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 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)

Consulte también

EvtInterruptWorkItem

WDF_INTERRUPT_CONFIG

WdfInterruptAcquireLock

WdfInterruptReleaseLock

WdfIoQueueRetrieveNextRequest

WdfRequestRequeue

WdfWaitLockAcquire