WdfWorkItemEnqueue, fonction (wdfworkitem.h)

[S’applique à KMDF et UMDF]

La méthode WdfWorkItemEnqueue ajoute un objet d’élément de travail d’infrastructure 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 pour un objet d’élément de travail d’infrastructure obtenu à partir d’un appel précédent à WdfWorkItemCreate.

Valeur de retour

None

Remarques

Un bogue case activée se produit si le pilote fournit un handle d’objet non valide.

Une fois que le pilote a appelé 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 dans lequel ils ont été ajoutés à la file d’attente.

Avant d’appeler 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 À nouveau WdfWorkItemEnqueue pour le même élément de travail avant qu’un thread de travail système n’ait mis en file d’attente l’élément de travail et appelé la fonction de rappel EvtWorkItem du pilote. Toutefois, KMDF n’ajoute pas l’élément de travail à la file d’attente s’il est déjà là. Par conséquent, votre fonction de rappel EvtWorkItem doit traiter tout le travail 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 la fin du premier élément de travail.

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 À nouveau WdfWorkItemEnqueue pour le même élément de travail tant qu’un thread de travail système n’a pas mis en file d’attente l’élément de travail et appelé sa fonction de rappel EvtWorkItem .

Pour plus d’informations sur les éléments de travail, consultez Utilisation d’éléments de travail framework.

Exemples

Cette section contient deux exemples. Le premier exemple montre comment ajouter des éléments de travail à une file d’attente pour KMDF versions 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 contextuelle de l’objet, puis appelle WdfWorkItemEnqueue. La fonction de rappel EvtWorkItem du pilote récupérera ultérieurement les informations de l’objet élément de travail.

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 à 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érera ultérieurement les informations de l’objet élément de travail.

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 de retour , le code définit la variable d’état de l’objet élément de travail sur « free » afin que le pilote puisse à nouveau mettre 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;
}

Configuration requise

Condition requise Valeur
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