Uso dei blocchi di Framework

A volte i driver devono fornire una sincronizzazione specifica del driver delle funzioni di callback relative alle richieste di I/O, oltre a o come sostituzione per la sincronizzazione fornita dal framework. I driver possono usare blocchi di sincronizzazione callback, blocchi di spin, blocchi di attesa e blocchi di interruzione per sincronizzare il codice driver.

Blocchi di sincronizzazione del callback

Se è stato configurato il driver per usare la funzionalità di sincronizzazione automatica del framework, il framework acquisisce un blocco di sincronizzazione prima di chiamare le funzioni di callback relative alle richieste di I/O del driver.

Questi blocchi di sincronizzazione del 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 del callback se il driver usa la sincronizzazione a livello di dispositivo o a livello di coda delle funzioni di callback di I/O, ma deve sincronizzare un codice eseguito in IRQL = PASSIVE_LEVEL con 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 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 di WDF_OBJECT_ATTRIBUTES di un oggetto dispositivo, il driver non può impostare il membro AutomaticSerialization della struttura di configurazione di un oggetto work-item 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 wait-lock. Il driver può quindi chiamare WdfWaitLockAcquire per acquisire il blocco e WdfWaitLockRelease per rilasciarlo.

Blocchi di spin framework

Usare i blocchi di rotazione 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 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 può usare un blocco spin per sincronizzare l'accesso allo spazio di contesto di un oggetto dispositivo, se lo spazio di contesto è scrivibile e se più funzioni di callback dell'evento del driver accedono allo spazio.

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

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

Blocchi di interruzione del framework

Per gli oggetti di interruzione che supportano la gestione degli interruzioni DIRQL, i blocchi di interruzione del framework sono blocchi di spin. Dopo che il driver acquisisce un blocco di spin di interruzione, il driver viene eseguito in DIRQL del dispositivo finché non rilascia il blocco. Per altre informazioni sull'uso di blocchi di interruzione, vedere Sincronizzazione del codice di interruzione.

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