Bagikan melalui


Fungsi WdfInterruptTryToAcquireLock (wdfinterrupt.h)

[Berlaku untuk KMDF dan UMDF]

Metode WdfInterruptTryToAcquireLock mencoba memperoleh kunci pasif objek interupsi.

Sintaks

BOOLEAN WdfInterruptTryToAcquireLock(
  [in] WDFINTERRUPT Interrupt
);

Parameter

[in] Interrupt

Handel ke objek interupsi kerangka kerja.

Nilai kembali

WdfInterruptTryToAcquireLock mengembalikan TRUE jika berhasil memperoleh kunci interupsi. Jika tidak, metode mengembalikan FALSE.

Keterangan

Driver yang menggunakan penanganan gangguan tingkat pasif memanggil WdfInterruptTryToAcquireLock untuk memulai urutan kode yang dijalankan di IRQL = PASSIVE_LEVEL sambil menahan kunci interupsi tingkat pasif yang dikonfigurasi driver dalam struktur WDF_INTERRUPT_CONFIG objek interupsi.

WdfInterruptTryToAcquireLock mencoba memperoleh kunci dan kemudian segera kembali, apakah telah memperoleh kunci atau tidak. Jika WdfInterruptTryToAcquireLock berhasil memperoleh kunci, kerangka kerja memanggil KeEnterCriticalRegion sebelum kembali sehingga APC kernel normal dinonaktifkan.

Untuk objek interupsi tingkat pasif, driver harus memanggil WdfInterruptTryToAcquireLock alih-alih WdfInterruptAcquireLock, saat berjalan dalam utas arbitrer, seperti fungsi panggilan balik objek antrean. Misalnya, driver mungkin memanggil WdfInterruptTryToAcquireLock dari EvtIoRead. Melakukannya menghindari kemungkinan kebuntuan, seperti yang dijelaskan di bagian Keterangan WdfInterruptAcquireLock.

Saat berjalan dalam utas non-arbitrer, seperti item kerja, driver harus menggunakan WdfInterruptAcquireLock.

Ketika driver memanggil WdfInterruptReleaseLock, kerangka kerja melepaskan kunci interupsi.

Contoh

Contoh kode berikut menunjukkan bagaimana fungsi panggilan balik EvtIoRead , berjalan dalam konteks arbitrer, mungkin memanggil WdfInterruptTryToAcquireLock sebelum melakukan pekerjaan terkait interupsi. Jika metode mengembalikan FALSE, driver mengantre item kerja untuk melakukan pekerjaan dalam utas non-arbitrer. Driver juga menyediakan fungsi panggilan balik EvtWorkItem yang memanggil WdfInterruptAcquireLock sebelum melakukan pekerjaan.

Dalam contoh ini, driver telah menentukan pengiriman berurutan untuk antrean. Jika driver menentukan metode pengiriman lain untuk antrean, driver harus menggunakan antrean manual tambahan untuk mempertahankan permintaan pemrosesan dalam item kerja. Komentar kode menjelaskan tempat untuk menambahkan dukungan tersebut.


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

Persyaratan

Persyaratan Nilai
Target Platform Universal
Versi KMDF minimum 1.11
Versi UMDF minimum 2.0
Header wdfinterrupt.h (termasuk Wdf.h)
Pustaka Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL PASSIVE_LEVEL
Aturan kepatuhan DDI DriverCreate(kmdf)

Lihat juga

EvtInterruptWorkItem

WDF_INTERRUPT_CONFIG

WdfInterruptAcquireLock

WdfInterruptReleaseLock

WdfIoQueueRetrieveNextRequest

WdfRequestRequeue

WdfWaitLockAcquire