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)
Library Wdf01000.sys (KMDF) ;WUDFx02000.dll (UMDF)
IRQL PASSIVE_LEVEL
DDI 符合性规则 DriverCreate (kmdf)

另请参阅

EvtInterruptWorkItem

WDF_INTERRUPT_CONFIG

WdfInterruptAcquireLock

WdfInterruptReleaseLock

WdfIoQueueRetrieveNextRequest

WdfRequestRequeue

WdfWaitLockAcquire