WdfWorkItemEnqueue, fonction (wdfworkitem.h)

[S’applique à KMDF et UMDF]

La méthode WdfWorkItemEnqueue ajoute un objet d’élément de travail framework spécifié à la file d’attente d’éléments de travail du système.

Syntaxe

void WdfWorkItemEnqueue(
  [in] WDFWORKITEM WorkItem
);

Paramètres

[in] WorkItem

Handle vers un objet d’élément de travail framework obtenu à partir d’un appel précédent à WdfWorkItemCreate.

Valeur de retour

None

Notes

Une vérification de bogue se produit si le pilote fournit un handle d’objet non valide.

Une fois que le pilote appelle WdfWorkItemCreate pour créer un élément de travail, le pilote doit appeler WdfWorkItemEnqueue pour ajouter l’élément de travail à la file d’attente d’éléments de travail du système. Un thread de travail système supprime ensuite l’élément de travail de la file d’attente et appelle la fonction de rappel EvtWorkItem de l’élément de travail. Le système supprime les éléments de travail dans l’ordre qu’ils ont été ajoutés à la file d’attente.

Avant que les pilotes appellent WdfWorkItemEnqueue, ils utilisent généralement la mémoire contextuelle de l’objet élément de travail pour stocker des informations sur l’élément de travail. La fonction de rappel EvtWorkItem utilise ces informations pour déterminer l’opération qu’elle doit effectuer.

Pour les versions 1.7 et ultérieures de KMDF, si votre pilote réutilise ses objets d’élément de travail, le pilote peut appeler WdfWorkItemEnqueue à nouveau pour le même élément de travail avant qu’un thread worker système ait supprimé l’élément de travail, puis appelé la fonction de rappel EvtWorkItem du pilote. Toutefois, KMDF n’ajoute pas l’élément de travail à la file d’attente s’il y est déjà. Par conséquent, votre fonction de rappel EvtWorkItem doit traiter tous les travaux mis en file d’attente chaque fois qu’il est appelé.

Votre pilote peut également appeler WdfWorkItemEnqueue pendant qu’une fonction de rappel EvtWorkItem est en cours d’exécution, pour mettre en file d’attente un autre élément de travail. Le rappel EvtWorkItem du deuxième élément de travail peut même s’exécuter avant que le premier ne se termine.

Dans les versions de KMDF antérieures à la version 1.7, si votre pilote réutilise ses objets d’élément de travail, il ne doit pas appeler de nouveau WdfWorkItemEnqueue pour le même élément de travail jusqu’à ce qu’un thread worker système ait supprimé l’élément de travail et appelé sa fonction de rappel EvtWorkItem .

Pour plus d’informations sur les éléments de travail, consultez Using Framework Work Items.

Exemples

Cette section contient deux exemples. Le premier exemple montre comment ajouter des éléments de travail à une file d’attente pour les versions KMDF 1.7 et ultérieures. Le deuxième exemple montre comment ajouter des éléments de travail à une file d’attente pour les versions KMDF antérieures à la version 1.7

Exemple 1 : KMDF versions 1.7 et ultérieures

L’exemple de code suivant appelle une routine locale qui retourne un pointeur vers la mémoire de contexte d’un objet d’élément de travail. L’exemple définit des informations dans la mémoire de contexte de l’objet, puis appelle WdfWorkItemEnqueue. La fonction de rappel EvtWorkItem du pilote récupère ultérieurement les informations de l’objet work-item.

PMY_CONTEXT_TYPE context;

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

WdfWorkItemEnqueue(hWorkItem);

La fonction de rappel EvtWorkItem du pilote contient le code suivant.

MyWorkItemCallback (
    IN WDFWORKITEM hWorkItem
    )
{
    PMY_CONTEXT_TYPE context;

    context = GetWorkItemContext(hWorkItem);

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

Exemple 2 : versions KMDF antérieures à la version 1.7

L’exemple de code suivant appelle une routine locale qui retourne un pointeur vers la mémoire de contexte d’un objet d’élément de travail. L’exemple définit des informations dans la mémoire de contexte de l’objet, définit une variable d’état sur « occupé », puis appelle WdfWorkItemEnqueue. La fonction de rappel EvtWorkItem du pilote récupère ultérieurement les informations de l’objet work-item.

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

La fonction de rappel EvtWorkItem du pilote contient le code suivant. Juste avant l’instruction return , le code définit la variable d’état de l’objet d’élément de travail sur « libre » afin que le pilote puisse mettre à nouveau l’objet en file d’attente.

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

Spécifications

   
Plateforme cible Universal
Version KMDF minimale 1.0
Version UMDF minimale 2.0
En-tête wdfworkitem.h (include Wdf.h)
Bibliothèque Wdf01000.sys (KMDF) ; WUDFx02000.dll (UMDF)
IRQL <= DISPATCH_LEVEL
Règles de conformité DDI DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf)

Voir aussi

EvtWorkItem

InterlockedCompareExchange

InterlockedExchange

WdfWorkItemCreate