WdfInterruptTryToAcquireLock-Funktion (wdfinterrupt.h)

[Gilt für KMDF und UMDF]

Die WdfInterruptTryToAcquireLock-Methode versucht, die passive Sperre eines Interruptobjekts abzurufen.

Syntax

BOOLEAN WdfInterruptTryToAcquireLock(
  [in] WDFINTERRUPT Interrupt
);

Parameter

[in] Interrupt

Ein Handle für ein Framework-Interruptobjekt.

Rückgabewert

WdfInterruptTryToAcquireLock gibt TRUE zurück, wenn die Sperre des Interrupts erfolgreich abgerufen wird. Andernfalls gibt die Methode FALSE zurück.

Hinweise

Treiber, die die Behandlung von Interrupts auf passiver Ebene verwenden, rufen WdfInterruptTryToAcquireLock auf, um eine Codesequenz zu starten, die unter IRQL = PASSIVE_LEVEL ausgeführt wird, während die Unterbrechungssperre auf passiver Ebene beibehalten wird, die der Treiber in der WDF_INTERRUPT_CONFIG-Struktur des Interruptobjekts konfiguriert hat.

WdfInterruptTryToAcquireLock versucht, die Sperre zu erwerben, und gibt dann sofort zurück, unabhängig davon, ob die Sperre erworben wurde oder nicht. Wenn WdfInterruptTryToAcquireLock die Sperre erfolgreich abruft, ruft das Framework KeEnterCriticalRegion auf, bevor es zurückgibt, sodass normale Kernel-APCs deaktiviert werden.

Bei Interruptobjekten auf passiver Ebene müssen Treiber WdfInterruptTryToAcquireLock anstelle von WdfInterruptAcquireLock aufrufen, wenn sie in einem beliebigen Thread ausgeführt werden, z. B. eine Rückruffunktion für Warteschlangenobjekte. Beispielsweise kann der Treiber WdfInterruptTryToAcquireLock aus EvtIoRead aufrufen. Dadurch wird die Möglichkeit eines Deadlocks vermieden, wie im Abschnitt "Hinweise" von WdfInterruptAcquireLock beschrieben.

Bei der Ausführung in einem nicht beliebigen Thread, z. B. einem Arbeitselement, sollte der Treiber WdfInterruptAcquireLock verwenden.

Wenn der Treiber WdfInterruptReleaseLock aufruft, gibt das Framework die Interruptsperre frei.

Beispiele

Das folgende Codebeispiel zeigt, wie eine EvtIoRead-Rückruffunktion , die in einem beliebigen Kontext ausgeführt wird, WdfInterruptTryToAcquireLock aufrufen kann, bevor sie interruptbezogene Arbeit ausführt. Wenn die Methode FALSE zurückgibt, stellt der Treiber ein Arbeitselement in die Warteschlange, um die Arbeit in einem nicht beliebigen Thread auszuführen. Der Treiber stellt auch eine EvtWorkItem-Rückruffunktion bereit, die WdfInterruptAcquireLock aufruft , bevor die Arbeit ausgeführt wird.

In diesem Beispiel hat der Treiber die sequenzielle Verteilung für die Warteschlange angegeben. Wenn der Treiber eine andere Verteilmethode für die Warteschlange angegeben hat, sollte der Treiber eine zusätzliche manuelle Warteschlange verwenden, um Anforderungen für die Verarbeitung im Arbeitselement beizubehalten. Codekommentare beschreiben, wo solche Unterstützung hinzugefügt werden soll.


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

Anforderungen

Anforderung Wert
Zielplattform Universell
KMDF-Mindestversion 1.11
UMDF-Mindestversion 2.0
Kopfzeile wdfinterrupt.h (einschließen von Wdf.h)
Bibliothek Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL PASSIVE_LEVEL
DDI-Complianceregeln DriverCreate(kmdf)

Weitere Informationen

EvtInterruptWorkItem

WDF_INTERRUPT_CONFIG

WdfInterruptAcquireLock

WdfInterruptReleaseLock

WdfIoQueueRetrieveNextRequest

WdfRequestRequeue

WdfWaitLockAcquire