WdfWorkItemEnqueue-Funktion (wdfworkitem.h)

[Gilt für KMDF und UMDF]

Die WdfWorkItemEnqueue-Methode fügt der Arbeitselementwarteschlange des Systems ein angegebenes Framework-Arbeitselementobjekt hinzu.

Syntax

void WdfWorkItemEnqueue(
  [in] WDFWORKITEM WorkItem
);

Parameter

[in] WorkItem

Ein Handle für ein Framework-Arbeitselementobjekt, das aus einem vorherigen Aufruf von WdfWorkItemCreate abgerufen wird.

Rückgabewert

Keine

Bemerkungen

Eine Fehlerüberprüfung tritt auf, wenn der Treiber ein ungültiges Objekthandle bereitstellt.

Nachdem der Treiber WdfWorkItemCreate aufgerufen hat, um ein Arbeitselement zu erstellen, muss der Treiber WdfWorkItemEnqueue aufrufen, um das Arbeitselement der Arbeitselementwarteschlange des Systems hinzuzufügen. Ein System-Workerthread entfernt anschließend das Arbeitselement aus der Warteschlange und ruft die EvtWorkItem-Rückruffunktion des Arbeitselements auf. Das System entfernt die Arbeitselemente in der Reihenfolge, in der sie der Warteschlange hinzugefügt wurden.

Bevor Treiber WdfWorkItemEnqueue aufrufen, verwenden sie in der Regel den Kontextspeicher des Arbeitselementobjekts, um Informationen zum Arbeitselement zu speichern. Die EvtWorkItem-Rückruffunktion verwendet diese Informationen, um den auszuführenden Vorgang zu bestimmen.

Wenn Ihr Treiber die Arbeitselementobjekte für die KmDF-Versionen 1.7 und höher wiederverwendet, kann der Treiber WdfWorkItemEnqueue erneut für dasselbe Arbeitselement aufrufen, bevor ein Systemarbeitsthread das Arbeitselement in die Warteschlange gestellt und anschließend die EvtWorkItem-Rückruffunktion des Treibers aufgerufen hat. KmDF fügt das Arbeitselement jedoch nicht zur Warteschlange hinzu, wenn es bereits vorhanden ist. Daher muss ihre EvtWorkItem-Rückruffunktion bei jedem Aufruf alle In die Warteschlange eingereihten Arbeiten verarbeiten.

Ihr Treiber kann auch WdfWorkItemEnqueue aufrufen, während eine EvtWorkItem-Rückruffunktion ausgeführt wird, um ein anderes Arbeitselement in die Warteschlange zu stellen. Der EvtWorkItem-Rückruf des zweiten Arbeitselements kann sogar ausgeführt werden, bevor das erste abgeschlossen ist.

Wenn Ihr Treiber in KMDF-Versionen vor Version 1.7 seine Arbeitselementobjekte wiederverwendet, darf er WdfWorkItemEnqueue erst dann erneut für dasselbe Arbeitselement aufrufen, wenn ein Systemarbeitsthread das Arbeitselement aus der Warteschlange entfernt und dessen EvtWorkItem-Rückruffunktion aufgerufen hat.

Weitere Informationen zu Arbeitselementen finden Sie unter Verwenden von Framework-Arbeitselementen.

Beispiele

Dieser Abschnitt enthält zwei Beispiele. Das erste Beispiel zeigt, wie Sie einer Warteschlange für KMDF-Versionen 1.7 und höher Arbeitselemente hinzufügen. Das zweite Beispiel zeigt, wie Sie einer Warteschlange für KMDF-Versionen vor Version 1.7 Arbeitselemente hinzufügen.

Beispiel 1: KMDF-Versionen 1.7 und höher

Im folgenden Codebeispiel wird eine lokale Routine aufgerufen, die einen Zeiger auf den Kontextspeicher eines Arbeitselementobjekts zurückgibt. Im Beispiel werden Informationen im Kontextspeicher des Objekts festgelegt und anschließend WdfWorkItemEnqueue aufgerufen. Die EvtWorkItem-Rückruffunktion des Treibers ruft später die Informationen aus dem Arbeitselementobjekt ab.

PMY_CONTEXT_TYPE context;

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

WdfWorkItemEnqueue(hWorkItem);

Die EvtWorkItem-Rückruffunktion des Treibers enthält den folgenden Code.

MyWorkItemCallback (
    IN WDFWORKITEM hWorkItem
    )
{
    PMY_CONTEXT_TYPE context;

    context = GetWorkItemContext(hWorkItem);

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

Beispiel 2: KMDF-Versionen vor 1.7

Im folgenden Codebeispiel wird eine lokale Routine aufgerufen, die einen Zeiger auf den Kontextspeicher eines Arbeitselementobjekts zurückgibt. Das Beispiel legt Informationen im Kontextspeicher des Objekts fest, legt eine Zustandsvariable auf "busy" fest und ruft dann WdfWorkItemEnqueue auf. Die EvtWorkItem-Rückruffunktion des Treibers ruft später die Informationen aus dem Arbeitselementobjekt ab.

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

Die EvtWorkItem-Rückruffunktion des Treibers enthält den folgenden Code. Unmittelbar vor der return-Anweisung legt der Code die Zustandsvariable des Arbeitselementobjekts auf "free" fest, sodass der Treiber das Objekt erneut in die Warteschlange stellen kann.

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

Anforderungen

Anforderung Wert
Zielplattform Universell
KMDF-Mindestversion 1.0
UMDF-Mindestversion 2.0
Kopfzeile wdfworkitem.h (include Wdf.h)
Bibliothek Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL <= DISPATCH_LEVEL
DDI-Complianceregeln DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf)

Weitere Informationen

EvtWorkItem

InterlockedCompareExchange

InterlockedExchange

WdfWorkItemCreate