WdfWorkItemEnqueue 函数 (wdfworkitem.h)

[适用于 KMDF 和 UMDF]

WdfWorkItemEnqueue 方法将指定的框架工作项对象添加到系统的工作项队列中。

语法

void WdfWorkItemEnqueue(
  [in] WDFWORKITEM WorkItem
);

参数

[in] WorkItem

从上一次调用 WdfWorkItemCreate获取的框架工作项对象的句柄。

返回值

没有

言论

如果驱动程序提供无效的对象句柄,则会发生 bug 检查。

驱动程序调用 WdfWorkItemCreate 来创建工作项后,驱动程序必须调用 WdfWorkItemEnqueue,才能将工作项添加到系统的工作项队列中。 系统工作线程随后从队列中删除工作项,并调用工作项 EvtWorkItem 回调函数。 系统按照添加到队列的顺序删除工作项。

在驱动程序调用 WdfWorkItemEnqueue之前,它们通常使用工作项对象的上下文内存来存储有关工作项的信息。 EvtWorkItem 回调函数使用此信息来确定它必须执行的作。

对于 KMDF 版本 1.7 及更高版本,如果驱动程序重复使用其工作项对象,驱动程序可以再次调用 WdfWorkItemEnqueue 相同的工作项,然后系统工作线程取消排队工作项,随后又调用驱动程序的 EvtWorkItem 回调函数。 但是,如果已存在,KMDF 将不会将工作项添加到队列。 因此,EvtWorkItem 回调函数每次调用时都必须处理所有排队的工作。

驱动程序还可以调用 WdfWorkItemEnqueue,同时运行 EvtWorkItem 回调函数,以对另一个工作项进行排队。 第二个工作项的 EvtWorkItem 回调甚至可能在第一个工作项完成之前运行。

在版本 1.7 之前的 KMDF 版本中,如果驱动程序重复使用其工作项对象,则它不得再次调用同一工作项 WdfWorkItemEnqueue,直到系统工作线程取消排队工作项并调用其 EvtWorkItem 回调函数。

有关工作项的详细信息,请参阅 使用框架工作项

例子

本部分包含两个示例。 第一个示例演示如何将工作项添加到 KMDF 版本 1.7 及更高版本的队列中。 第二个示例演示如何将工作项添加到版本 1.7 之前的 KMDF 版本的队列

示例 1:KMDF 版本 1.7 及更高版本

下面的代码示例调用一个本地例程,该例程返回指向工作项对象的上下文内存的指针。 该示例设置对象上下文内存中的信息,然后调用 WdfWorkItemEnqueue。 驱动程序的 EvtWorkItem 回调函数稍后将从工作项对象中检索信息。

PMY_CONTEXT_TYPE context;

context = GetWorkItemContext(hWorkItem);
context->FdoData = FdoData;
context->Argument1 = Context1;
context->Argument2 = Context2;

WdfWorkItemEnqueue(hWorkItem);

驱动程序的 EvtWorkItem 回调函数包含以下代码。

MyWorkItemCallback (
    IN WDFWORKITEM hWorkItem
    )
{
    PMY_CONTEXT_TYPE context;

    context = GetWorkItemContext(hWorkItem);

    //
    // Do work here.
    //
    ...
    //
    return;
}

示例 2:1.7 之前的 KMDF 版本

下面的代码示例调用一个本地例程,该例程返回指向工作项对象的上下文内存的指针。 该示例设置对象上下文内存中的信息,将状态变量设置为“busy”,然后调用 WdfWorkItemEnqueue。 驱动程序的 EvtWorkItem 回调函数稍后将从工作项对象中检索信息。

typedef enum _WORKITEM_STATE {
    WORKITEM_STATE_FREE =0,
    WORKITEM_STATE_BUSY = 1
} WORKITEM_STATE;
...
PMY_CONTEXT_TYPE context;

context = GetWorkItemContext(hWorkItem);
context->FdoData = FdoData;
context->Argument1 = Context1;
context->Argument2 = Context2;

if (InterlockedCompareExchange(
                               (PLONG)&context->WorkItemState,
                               WORKITEM_STATE_BUSY,
                               WORKITEM_STATE_FREE
                               ) == WORKITEM_STATE_FREE) {
 WdfWorkItemEnqueue(hWorkItem);
}

驱动程序的 EvtWorkItem 回调函数包含以下代码。 就在 返回 语句之前,代码会将工作项对象的状态变量设置为“free”,以便驱动程序可以再次对对象进行排队。

MyWorkItemCallback (
    IN WDFWORKITEM hWorkItem
    )
{
    PMY_CONTEXT_TYPE context;
    LONG result;

    context = GetWorkItemContext(hWorkItem);

    //
    // Do work here.
    //
    ...
    //
    // Reset object state.
    //
    result = InterlockedExchange(
                                 (PLONG)&context->WorkItemState,
                                 WORKITEM_STATE_FREE
                                 );
    ASSERT(result == WORKITEM_STATE_BUSY);
    return;
}

要求

要求 价值
目标平台 普遍
最低 KMDF 版本 1.0
最低 UMDF 版本 2.0
标头 wdfworkitem.h (包括 Wdf.h)
Wdf01000.sys(KMDF):WUDFx02000.dll (UMDF)
IRQL <= DISPATCH_LEVEL
DDI 符合性规则 DeferredRequestCompleted(kmdf)DriverCreate(kmdf)KmdfIrql(kmdf)KmdfIrql2(kmdf),KmdfIrqlExplicit(kmdf),RequestCompleted(kmdf)RequestCompletedLocal(kmdf)

另请参阅

EvtWorkItem

InterlockedCompareExchange

InterlockedExchange

WdfWorkItemCreate