WdfWorkItemEnqueue-Funktion (wdfworkitem.h)

[Gilt für KMDF und UMDF]

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

Syntax

void WdfWorkItemEnqueue(
  [in] WDFWORKITEM WorkItem
);

Parameter

[in] WorkItem

Ein Handle zu einem Framework-Arbeitselementobjekt, das von 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 eine Arbeitsaufgabe zu erstellen, muss der Treiber WdfWorkItemEnqueue aufrufen, um die Arbeitsaufgabe der Arbeitselementwarteschlange des Systems hinzuzufügen. Ein Systemarbeitsthread entfernt anschließend die Arbeitsaufgabe aus der Warteschlange und ruft die EvtWorkItem-Rückruffunktion der Arbeitsaufgabe 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 Arbeitselements, um Informationen zum Arbeitselement zu speichern. Die Rückruffunktion EvtWorkItem verwendet diese Informationen, um den auszuführenden Vorgang zu ermitteln.

Wenn Der Treiber für Versionen 1.7 und höher von KMDF seine Arbeitselementobjekte wiederverwendet, kann der Treiber WdfWorkItemEnqueue erneut für dieselbe Arbeitsaufgabe aufrufen, bevor ein Systemarbeitsthread die Arbeitsaufgabe entqueuiert hat und anschließend die EvtWorkItem-Rückruffunktion des Treibers aufgerufen hat. KMDF fügt jedoch die Arbeitsaufgabe nicht zur Warteschlange hinzu, wenn sie bereits vorhanden ist. Daher muss Ihre EvtWorkItem-Rückruffunktion jedes Mal, wenn sie aufgerufen wird, alle in die Warteschlange gestellten Arbeiten verarbeiten.

Ihr Treiber kann auch WdfWorkItemEnqueue aufrufen, während eine EvtWorkItem-Rückruffunktion ausgeführt wird, um eine andere Arbeitsaufgabe in die Warteschlange zu stellen. Der EvtWorkItem-Rückruf der zweiten Arbeitsaufgabe kann sogar ausgeführt werden, bevor die erste abgeschlossen wird.

In Versionen von KMDF vor Version 1.7 darf WdfWorkItemEnqueue nicht erneut für dieselbe Arbeitsaufgabe aufgerufen werden, bis ein Systemarbeitsthread die Arbeitsaufgabe dequeuiert und seine 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 KMDF-Version 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 dann WdfWorkItemEnqueue aufgerufen. Die Rückruffunktion des Treibers EvtWorkItem 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. Im Beispiel werden Informationen im Kontextspeicher des Objekts festgelegt, eine Zustandsvariable auf "beschäftigt" festgelegt und dann WdfWorkItemEnqueue aufgerufen. Die Rückruffunktion des Treibers EvtWorkItem 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. Vor der Rückgabe-Anweisung legt der Code die Statusvariable des Arbeitselementobjekts auf "frei" fest, damit 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

   
Zielplattform Universell
KMDF-Mindestversion 1.0
UMDF-Mindestversion 2.0
Header 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)

Siehe auch

EvtWorkItem

InterlockedCompareExchange

InterlockedExchange

WdfWorkItemCreate