Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
[Применимо к KMDF и UMDF]
Метод WdfWorkItemEnqueue добавляет указанный объект рабочей платформы в очередь рабочих элементов системы.
Синтаксис
void WdfWorkItemEnqueue(
[in] WDFWORKITEM WorkItem
);
Параметры
[in] WorkItem
Дескриптор объекта рабочего элемента платформы, полученный из предыдущего вызова WdfWorkItemCreate.
Возвращаемое значение
Никакой
Замечания
Ошибка возникает, если драйвер предоставляет недопустимый дескриптор объекта.
После вызова драйвера WdfWorkItemCreate для создания рабочего элемента драйвер должен вызвать WdfWorkItemEnqueue, чтобы добавить рабочий элемент в очередь рабочих элементов системы. Системный рабочий поток впоследствии удаляет рабочий элемент из очереди и вызывает функцию обратного вызова рабочего элемента EvtWorkItem. Система удаляет рабочие элементы в том порядке, в который они были добавлены в очередь.
Прежде чем драйверы вызывают WdfWorkItemEnqueue, обычно используют память контекста объекта рабочего элемента для хранения сведений о рабочем элементе. Функция обратного вызова EvtWorkIte m использует эти сведения для определения операции, которую необходимо выполнить.
Для версий 1.7 и более поздних версий KMDF, если драйвер повторно использует свои объекты рабочего элемента, драйвер может вызывать WdfWorkItemEnqueue для того же рабочего элемента, прежде чем системный рабочий поток отменил рабочий элемент и впоследствии назвал функцию обратного вызова драйвера EvtWorkItem. Однако KMDF не добавит рабочий элемент в очередь, если он уже есть. Поэтому функция обратного вызова EvtWorkItem должна обрабатывать все работы в очереди при каждом вызове.
Драйвер также может вызывать WdfWorkItemEnqueue во время выполнения функции обратного вызова EvtWorkItem для очереди другого рабочего элемента. Второй рабочий элемент EvtWorkItem обратный вызов может даже выполняться до завершения первого элемента.
В версиях KMDF до версии 1.7, если драйвер повторно использует свои объекты рабочих элементов, он не должен вызывать WdfWorkItemEnqueue для того же рабочего элемента, пока системный рабочий поток не отменил рабочий элемент и назвал его EvtWorkItem функцию обратного вызова.
Дополнительные сведения о рабочих элементах см. в разделе Using Framework Work Items.
Примеры
Этот раздел содержит два примера. В первом примере показано, как добавить рабочие элементы в очередь для KMDF версий 1.7 и более поздних версий. Второй пример показывает, как добавить рабочие элементы в очередь для версий KMDF до версии 1.7.
пример 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: версии KMDF до версии 1.7
В следующем примере кода вызывается локальная подпрограмма, которая возвращает указатель на память контекста объекта рабочего элемента. Пример задает сведения в памяти контекста объекта, задает для переменной состояния значение "занято", а затем вызывает 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 содержит следующий код. Непосредственно перед возвратом инструкции код задает для переменной состояния объекта рабочего элемента значение "бесплатный", чтобы драйвер смог снова ставить объект в очередь.
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 (include 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) |