Uso dei blocchi del framework

In alcuni casi i driver devono fornire la sincronizzazione specifica del driver delle funzioni di callback correlate alle richieste di I/O, in aggiunta o in sostituzione della sincronizzazione fornita dal framework. I driver possono usare blocchi di sincronizzazione di callback, blocchi di spin, blocchi di attesa e blocchi di interrupt per sincronizzare il codice del driver.

Blocchi di sincronizzazione dei callback

Se il driver è stato configurato per l'uso della funzionalità di sincronizzazione automatica del framework, il framework acquisisce un blocco di sincronizzazione prima di chiamare le funzioni di callback degli eventi relative alle richieste di I/O del driver.

Questi blocchi di sincronizzazione di callback, associati agli oggetti dispositivo framework e agli oggetti coda, possono essere acquisiti anche dai driver. Per acquisire un blocco di sincronizzazione, un driver chiama WdfObjectAcquireLock. Per rilasciare il blocco, il driver chiama WdfObjectReleaseLock.

È possibile che il driver usi i blocchi di sincronizzazione di callback se il driver usa la sincronizzazione a livello di dispositivo o a livello di coda del framework delle funzioni di callback correlate alle richieste di I/O, ma deve sincronizzare il codice eseguito in IRQL = PASSIVE_LEVEL con le funzioni di callback eseguite in IRQL = DISPATCH_LEVEL. Questo perché i driver possono usare la sincronizzazione automatica solo per le funzioni di callback eseguite nello stesso IRQL.

Ad esempio, un driver può usare la sincronizzazione automatica per un oggetto elemento di lavoro solo se il livello di esecuzione dell'oggetto padre dell'elemento di lavoro è WdfExecutionLevelPassive (perché la funzione di callback di un elemento di lavoro viene sempre eseguita in IRQL= PASSIVE_LEVEL). Pertanto, se un driver specifica WdfExecutionLevelDispatch nel membro ExecutionLevel della struttura WDF_OBJECT_ATTRIBUTES di un oggetto dispositivo, il driver non può impostare il membro AutomaticSerialization della struttura di configurazione di un oggetto elemento di lavoro figlio. Il driver deve invece acquisire un blocco di sincronizzazione callback per sincronizzare le funzioni di callback EvtWorkItem con le funzioni di callback dell'oggetto dispositivo padre.

Blocchi di attesa del framework

Usare i blocchi di attesa del framework per sincronizzare l'accesso ai dati del driver dal codice eseguito in IRQL = PASSIVE_LEVEL. Prima che un driver possa usare un blocco di attesa del framework, deve chiamare WdfWaitLockCreate per creare un oggetto di blocco di attesa. Il driver può quindi chiamare WdfWaitLockAcquire per acquisire il blocco e WdfWaitLockRelease per rilasciarlo.

Blocchi di selezione del framework

Usare i blocchi di selezione del framework per sincronizzare l'accesso ai dati del driver dal codice eseguito in IRQL <= DISPATCH_LEVEL. Quando un thread del driver acquisisce un blocco di rotazione, il sistema imposta l'IRQL del thread su DISPATCH_LEVEL. Quando il thread rilascia il blocco, il sistema ripristina l'IRQL del thread al livello precedente.

Un driver che non usa la sincronizzazione automatica del framework potrebbe usare un blocco di selezione per sincronizzare l'accesso allo spazio di contesto di un oggetto dispositivo, se lo spazio di contesto è scrivibile e se più funzioni di callback degli eventi del driver accedono allo spazio.

Prima che un driver possa usare un blocco di spin del framework, deve chiamare WdfSpinLockCreate per creare un oggetto di blocco di spin. Il driver può quindi chiamare WdfSpinLockAcquire per acquisire il blocco e WdfSpinLockRelease per rilasciarlo.

Per un esempio di uso dei blocchi di selezione, vedere Sincronizzazione dell'annullamento delle richieste inviate.

Blocchi di interrupt del framework

Per gli oggetti interrupt che supportano la gestione degli interrupt DIRQL, i blocchi di interrupt del framework sono blocchi di rotazione. Dopo che il driver acquisisce un blocco di spin di interrupt, il driver viene eseguito in corrispondenza del DIRQL del dispositivo fino a quando non rilascia il blocco. Per altre informazioni sull'uso dei blocchi di interrupt, vedere Sincronizzazione del codice di interrupt.

Per gli oggetti interrupt che supportano la gestione a livello passivo, i blocchi di interrupt del framework sono blocchi di attesa. Dopo che il driver acquisisce un blocco di attesa di interrupt, il driver viene eseguito in IRQL = PASSIVE_LEVEL finché non rilascia il blocco. Per altre informazioni sulla gestione a livello passivo, vedere Supporto di interrupt a livello passivo.