Compartilhar via


Função WdfInterruptTryToAcquireLock (wdfinterrupt.h)

[Aplica-se a KMDF e UMDF]

O método WdfInterruptTryToAcquireLock tenta adquirir o bloqueio passivo de um objeto de interrupção.

Sintaxe

BOOLEAN WdfInterruptTryToAcquireLock(
  [in] WDFINTERRUPT Interrupt
);

Parâmetros

[in] Interrupt

Um identificador para um objeto de interrupção de estrutura.

Retornar valor

WdfInterruptTryToAcquireLock retornará TRUE se adquirir com êxito o bloqueio da interrupção. Caso contrário, o método retornará FALSE.

Comentários

Os drivers que usam o tratamento de interrupção de nível passivo chamam WdfInterruptTryToAcquireLock para iniciar uma sequência de código que é executada em IRQL = PASSIVE_LEVEL mantendo o bloqueio de interrupção de nível passivo configurado pelo driver na estrutura WDF_INTERRUPT_CONFIG do objeto de interrupção.

WdfInterruptTryToAcquireLock tenta adquirir o bloqueio e retorna imediatamente, quer tenha adquirido o bloqueio ou não. Se WdfInterruptTryToAcquireLock adquirir com êxito o bloqueio, a estrutura chamará KeEnterCriticalRegion antes de retornar para que as APCs de kernel normais sejam desabilitadas.

Para objetos de interrupção de nível passivo, os drivers devem chamar WdfInterruptTryToAcquireLock em vez de WdfInterruptAcquireLock, ao executar em um thread arbitrário, como uma função de retorno de chamada de objeto de fila. Por exemplo, o driver pode chamar WdfInterruptTryToAcquireLock de EvtIoRead. Isso evita a possibilidade de deadlock, conforme descrito na seção Comentários de WdfInterruptAcquireLock.

Ao executar em um thread não arbitrário, como um item de trabalho, o driver deve usar WdfInterruptAcquireLock.

Quando o driver chama WdfInterruptReleaseLock, a estrutura libera o bloqueio de interrupção.

Exemplos

O exemplo de código a seguir mostra como uma função de retorno de chamada EvtIoRead , em execução em um contexto arbitrário, pode chamar WdfInterruptTryToAcquireLock antes de executar o trabalho relacionado à interrupção. Se o método retornar FALSE, o driver enfileira um item de trabalho para executar o trabalho em um thread não arbitrário. O driver também fornece uma função de retorno de chamada EvtWorkItem que chama WdfInterruptAcquireLock antes de executar o trabalho.

Neste exemplo, o driver especificou a expedição sequencial para a fila. Se o driver especificou qualquer outro método de expedição para a fila, o driver deverá usar uma fila manual adicional para reter solicitações de processamento no item de trabalho. Os comentários de código descrevem onde adicionar esse suporte.


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
Plataforma de Destino Universal
Versão mínima do KMDF 1.11
Versão mínima do UMDF 2,0
Cabeçalho wdfinterrupt.h (inclua Wdf.h)
Biblioteca Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL PASSIVE_LEVEL
Regras de conformidade da DDI DriverCreate(kmdf)

Confira também

EvtInterruptWorkItem

WDF_INTERRUPT_CONFIG

WdfInterruptAcquireLock

WdfInterruptReleaseLock

WdfIoQueueRetrieveNextRequest

WdfRequestRequeue

WdfWaitLockAcquire