Verwenden von Frameworksperren

Manchmal müssen Treiber eine treiberspezifische Synchronisierung von anforderungsbezogenen E/A-Rückruffunktionen bereitstellen, entweder zusätzlich zu oder als Ersatz für die vom Framework bereitgestellte Synchronisierung. Treiber können Rückrufsynchronisierungssperren, Drehsperren, Wartesperren und Interruptsperren verwenden, um Treibercode zu synchronisieren.

Rückrufsynchronisierungssperren

Wenn Sie Ihren Treiber für die Verwendung der automatischen Synchronisierungsfunktion des Frameworks eingerichtet haben, ruft das Framework vor dem Aufrufen der E/A-Anforderungs-Ereignisrückruffunktionen des Treibers eine Synchronisierungssperre ab.

Diese Rückrufsynchronisierungssperren, die Frameworkgeräteobjekten und Warteschlangenobjekten zugeordnet sind, können auch von Treibern abgerufen werden. Um eine Synchronisierungssperre zu erhalten, ruft ein Treiber WdfObjectAcquireLock auf. Um die Sperre freizugeben, ruft der Treiber WdfObjectReleaseLock auf.

Möglicherweise möchten Sie, dass Ihr Treiber die Rückrufsynchronisierungssperren verwendet, wenn der Treiber die Synchronisierung auf Geräte- oder Warteschlangenebene des Frameworks für E/A-Rückruffunktionen verwendet, aber code, der unter IRQL = PASSIVE_LEVEL ausgeführt wird, mit Rückruffunktionen synchronisieren muss, die unter IRQL = DISPATCH_LEVEL ausgeführt werden. Dies liegt daran, dass Treiber die automatische Synchronisierung nur für Rückruffunktionen verwenden können, die im selben IRQL ausgeführt werden.

Beispielsweise kann ein Treiber die automatische Synchronisierung für ein Arbeitselementobjekt nur verwenden, wenn die Ausführungsebene des übergeordneten Arbeitselementobjekts WdfExecutionLevelPassive ist (da die Rückruffunktion eines Arbeitselements immer bei IRQL= PASSIVE_LEVEL ausgeführt wird). Wenn ein Treiber WdfExecutionLevelDispatch im ExecutionLevel-Member der WDF_OBJECT_ATTRIBUTES-Struktur eines Geräteobjekts angibt, kann der Treiber daher den AutomaticSerialization-Member der Konfigurationsstruktur eines untergeordneten Arbeitselementobjekts nicht festlegen. Stattdessen muss der Treiber eine Rückrufsynchronisierungssperre abrufen, um die EvtWorkItem-Rückruffunktionen mit den Rückruffunktionen des übergeordneten Geräteobjekts zu synchronisieren.

Framework-Wartesperren

Verwenden Sie Framework-Wartesperren, um den Zugriff auf Treiberdaten aus Code zu synchronisieren, der unter IRQL = PASSIVE_LEVEL ausgeführt wird. Bevor ein Treiber eine Framework-Wartesperre verwenden kann, muss er WdfWaitLockCreate aufrufen, um ein Wartesperrobjekt zu erstellen. Der Treiber kann dann WdfWaitLockAcquire aufrufen, um die Sperre zu erhalten, und WdfWaitLockRelease , um sie freizugeben.

Framework-Spinsperren

Verwenden Sie Framework-Spinsperren, um den Zugriff auf Treiberdaten aus Code zu synchronisieren, der unter IRQL <= DISPATCH_LEVEL ausgeführt wird. Wenn ein Treiberthread eine Drehsperre erhält, legt das System die IRQL des Threads auf DISPATCH_LEVEL fest. Wenn der Thread die Sperre freigibt, stellt das System die IRQL des Threads auf die vorherige Ebene wieder her.

Ein Treiber, der keine automatische Frameworksynchronisierung verwendet, kann eine Drehsperre verwenden, um den Zugriff auf den Kontextbereich eines Geräteobjekts zu synchronisieren, wenn der Kontextbereich beschreibbar ist und mehr als eine der Ereignisrückruffunktionen des Treibers auf den Bereich zugreifen.

Bevor ein Treiber eine Framework-Spinsperre verwenden kann, muss er WdfSpinLockCreate aufrufen, um ein Spin-Lock-Objekt zu erstellen. Der Treiber kann dann WdfSpinLockAcquire aufrufen, um die Sperre zu erhalten, und WdfSpinLockRelease , um sie freizugeben.

Ein Beispiel für die Verwendung von Spinsperren finden Sie unter Synchronisieren des Abbruchs von gesendeten Anforderungen.

Framework-Interruptsperren

Für Interruptobjekte, die die DIRQL-Interruptbehandlung unterstützen, sind Framework-Interruptsperren Spinsperren. Nachdem Ihr Treiber eine Interrupt-Spin-Sperre erworben hat, wird der Treiber am DIRQL des Geräts ausgeführt, bis er die Sperre loslässt. Weitere Informationen zur Verwendung von Interruptsperren finden Sie unter Synchronisieren von Interruptcode.

Bei Interruptobjekten, die die verarbeitung auf passiver Ebene unterstützen, sind Frameworkunterbrechungssperren Wartesperren. Nachdem Ihr Treiber eine Interrupt-Wartesperre erhalten hat, wird der Treiber unter IRQL = PASSIVE_LEVEL ausgeführt, bis die Sperre aufgehoben wird. Weitere Informationen zur Behandlung auf passiver Ebene finden Sie unter Unterstützen von Passive Level Interrupts.