Partager via


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 work-item framework obtenu à partir d’un appel précédent à WdfWorkItemCreate.

Valeur de retour

Aucun

Remarques

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 EvtWorkItem fonction de rappel 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 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 de travail système n’ait mis en file d’attente l’élément de travail, puis appelé EvtWorkItem fonction de rappel. Toutefois, KMDF n’ajoute pas l’élément de travail à la file d’attente s’il y est déjà. Par conséquent, votre EvtWorkItem fonction de rappel 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 deuxième élément de travail EvtWorkItem rappel peut même s’exécuter avant la fin du premier.

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 WdfWorkItemEnqueue à nouveau pour le même élément de travail jusqu’à ce qu’un thread de travail système ait mis en file d’attente l’élément de travail et appelé son EvtWorkItem fonction de rappel.

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 1.7 et ultérieures de KMDF. 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 contextuelle 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ère ultérieurement les informations de l’objet d’é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 à la version 1.7

L’exemple de code suivant appelle une routine locale qui retourne un pointeur vers la mémoire contextuelle d’un objet d’élément de travail. L’exemple définit des informations dans la mémoire contextuelle 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 d’é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 que le retourne instruction, le code définit la variable d’état de l’objet d’é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;
}

Exigences

Exigence Valeur
plateforme cible Universel
version minimale de KMDF 1.0
version minimale de UMDF 2.0
d’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), Km, KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf)

Voir aussi

EvtWorkItem

InterlockedCompareExchange

interlockedExchange

WdfWorkItemCreate