Funzione WdfWorkItemEnqueue (wdfworkitem.h)
[Si applica a KMDF e UMDF]
Il metodo WdfWorkItemEnqueue aggiunge un oggetto work-item framework specificato alla coda dell'elemento di lavoro del sistema.
Sintassi
void WdfWorkItemEnqueue(
[in] WDFWORKITEM WorkItem
);
Parametri
[in] WorkItem
Handle a un oggetto elemento di lavoro del framework ottenuto da una chiamata precedente a WdfWorkItemCreate.
Valore restituito
nessuno
Osservazioni
Un controllo di bug si verifica se il driver fornisce un handle di oggetti non valido.
Dopo che il driver chiama WdfWorkItemCreate per creare un elemento di lavoro, il driver deve chiamare WdfWorkItemEnqueue per aggiungere l'elemento di lavoro alla coda dell'elemento di lavoro del sistema. Un thread di lavoro di sistema rimuove successivamente l'elemento di lavoro dalla coda e chiama la funzione di callback evtWorkItem dell'elemento di lavoro. Il sistema rimuove gli elementi di lavoro nell'ordine in cui sono stati aggiunti alla coda.
Prima che i driver chiamino WdfWorkItemEnqueue, in genere usano la memoria del contesto dell'elemento di lavoro per archiviare informazioni sull'elemento di lavoro. La funzione di callback EvtWorkItem usa queste informazioni per determinare l'operazione che deve eseguire.
Per le versioni 1.7 e successive di KMDF, se il driver riutilizza gli oggetti dell'elemento di lavoro, il driver può chiamare nuovamente WdfWorkItemEnqueue per lo stesso elemento di lavoro prima che un thread di lavoro di sistema abbia dequeuato l'elemento di lavoro e successivamente chiamato la funzione di callback evtWorkItem del driver. Tuttavia, KMDF non aggiungerà l'elemento di lavoro alla coda se è già presente. Pertanto, la funzione di callback EvtWorkItem deve elaborare tutto il lavoro in coda ogni volta che viene chiamato.
Il driver può anche chiamare WdfWorkItemEnqueue mentre è in esecuzione una funzione di callback EvtWorkItem per accodare un altro elemento di lavoro. Il callback evtWorkItem del secondo elemento di lavoro potrebbe essere eseguito anche prima del completamento della prima.
Nelle versioni di KMDF precedenti alla versione 1.7, se il driver riutilizza gli oggetti dell'elemento di lavoro, non deve chiamare di nuovo WdfWorkItemEnqueue per lo stesso elemento di lavoro finché non viene dequeuato l'elemento di lavoro e chiamato la funzione di callback evtWorkItem .
Per altre informazioni sugli elementi di lavoro, vedere Uso degli elementi di lavoro di Framework.
Esempio
Questa sezione contiene due esempi. Il primo esempio illustra come aggiungere elementi di lavoro a una coda per kmDF versioni 1.7 e successive. Il secondo esempio illustra come aggiungere elementi di lavoro a una coda per le versioni kmDF precedenti alla versione 1.7
Esempio 1: KMDF versione 1.7 e successiva
Nell'esempio di codice seguente viene chiamata una routine locale che restituisce un puntatore alla memoria di contesto di un oggetto dell'elemento di lavoro. L'esempio imposta informazioni nella memoria del contesto dell'oggetto e quindi chiama WdfWorkItemEnqueue. La funzione di callback EvtWorkItem del driver recupera le informazioni dall'oggetto elemento di lavoro.
PMY_CONTEXT_TYPE context;
context = GetWorkItemContext(hWorkItem);
context->FdoData = FdoData;
context->Argument1 = Context1;
context->Argument2 = Context2;
WdfWorkItemEnqueue(hWorkItem);
La funzione di callback EvtWorkItem del driver contiene il codice seguente.
MyWorkItemCallback (
IN WDFWORKITEM hWorkItem
)
{
PMY_CONTEXT_TYPE context;
context = GetWorkItemContext(hWorkItem);
//
// Do work here.
//
...
//
return;
}
Esempio 2: versioni di KMDF precedenti alla versione 1.7
Nell'esempio di codice seguente viene chiamata una routine locale che restituisce un puntatore alla memoria di contesto di un oggetto dell'elemento di lavoro. L'esempio imposta informazioni nella memoria del contesto dell'oggetto, imposta una variabile di stato su "occupato" e quindi chiama WdfWorkItemEnqueue. La funzione di callback EvtWorkItem del driver recupera le informazioni dall'oggetto elemento di lavoro.
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 funzione di callback EvtWorkItem del driver contiene il codice seguente. Subito prima dell'istruzione restituita , il codice imposta la variabile di stato dell'oggetto work-item su "free" in modo che il driver possa accodare di nuovo l'oggetto.
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;
}
Requisiti
Requisito | Valore |
---|---|
Piattaforma di destinazione | Universale |
Versione KMDF minima | 1.0 |
Versione UMDF minima | 2,0 |
Intestazione | wdfworkitem.h (includere Wdf.h) |
Libreria | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL | <= DISPATCH_LEVEL |
Regole di conformità DDI | DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf) |