WdfInterruptTryToAcquireLock 函数 (wdfinterrupt.h)

[适用于 KMDF 和 UMDF]

WdfInterruptTryToAcquireLock 方法尝试获取中断对象的被动锁。

语法

BOOLEAN WdfInterruptTryToAcquireLock(
  [in] WDFINTERRUPT Interrupt
);

参数

[in] Interrupt

框架中断对象的句柄。

返回值

WdfInterruptTryToAcquireLock 如果成功获取中断的锁,则返回 TRUE。 否则,该方法返回 FALSE。

注解

使用 被动级中断处理的驱动程序 调用 WdfInterruptTryToAcquireLock 启动在 IRQL = PASSIVE_LEVEL 中执行的代码序列,同时保留驱动程序在中断对象的 WDF_INTERRUPT_CONFIG 结构中配置的被动级中断锁。

WdfInterruptTryToAcquireLock 尝试获取锁,然后立即返回,无论它是否已获取锁。 如果 WdfInterruptTryToAcquireLock 成功获取锁,则框架会在返回前调用 KeEnterCriticalRegion,以便禁用正常的内核 APC。

对于被动级中断对象,驱动程序必须在任意线程中运行时调用 WdfInterruptTryToAcquireLock 而不是 WdfInterruptAcquireLock,例如 队列对象回调函数。 例如,驱动程序可以从 EvtIoRead调用 WdfInterruptTryToAcquireLock。 这样做可以避免死锁的可能性,如 WdfInterruptAcquireLock的“备注”部分所述。

在非任意线程(如工作项)中运行时,驱动程序应使用 WdfInterruptAcquireLock

当驱动程序调用 WdfInterruptReleaseLock时,框架会释放中断锁。

例子

下面的代码示例演示如何在任意上下文中运行的 EvtIoRead 回调函数在执行中断相关工作之前调用 WdfInterruptTryToAcquireLock。 如果该方法返回 FALSE,驱动程序会将工作项排入队列,以在非任意线程中执行该工作。 驱动程序还提供了一个 EvtWorkItem 回调函数,该函数在执行工作之前调用 WdfInterruptAcquireLock

在此示例中,驱动程序已为队列指定了 顺序 调度。 如果指定的驱动程序 队列的任何其他调度方法,驱动程序应使用额外的手动队列来保留在工作项中处理的请求。 代码注释描述添加此类支持的位置。


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

要求

要求 价值
目标平台 普遍
最低 KMDF 版本 1.11
最低 UMDF 版本 2.0
标头 wdfinterrupt.h (包括 Wdf.h)
图书馆 Wdf01000.sys(KMDF):WUDFx02000.dll (UMDF)
IRQL PASSIVE_LEVEL
DDI 符合性规则 DriverCreate(kmdf)

另请参阅

EvtInterruptWorkItem

WDF_INTERRUPT_CONFIG

WdfInterruptAcquireLock

WdfInterruptReleaseLock

WdfIoQueueRetrieveNextRequest

WdfRequestRequeue

WdfWaitLockAcquire