使用框架锁
有时,驱动程序必须提供与 I/O 请求相关的回调函数的特定于驱动程序的同步,或者作为框架提供的同步的替代。 驱动程序可以使用回调同步锁、旋转锁、等待锁和中断锁来同步驱动程序代码。
回调同步锁
如果已将驱动程序设置为使用框架的 自动同步 功能,则框架在调用驱动程序的 I/O 请求相关事件回调函数之前获取同步锁。
驱动程序也可以获取与框架设备对象和队列对象关联的 这些回调同步锁。 若要获取同步锁,驱动程序会调用 WdfObjectAcquireLock。 若要释放锁,驱动程序会调用 WdfObjectReleaseLock。
如果驱动程序使用框架的设备级或队列级 I/O 请求相关回调函数同步,但必须将在 IRQL = PASSIVE_LEVEL 上运行的某些代码与在 IRQL = DISPATCH_LEVEL 运行的回调函数同步,则你可能希望驱动程序使用回调同步锁。 这是因为驱动程序只能对在同一 IRQL 处执行的回调函数使用自动同步。
例如,仅当工作项对象的父对象的执行级别为 WdfExecutionLevelPassive (时,驱动程序才能对工作项对象使用自动同步,因为工作项的回调函数始终在 IRQL= PASSIVE_LEVEL) 执行。 因此,如果驱动程序在设备对象的 WDF_OBJECT_ATTRIBUTES 结构的 ExecutionLevel 成员中指定 WdfExecutionLevelDispatch,则驱动程序无法设置子工作项对象的配置结构的 AutomaticSerialization 成员。 相反,驱动程序必须获取回调同步锁才能将 EvtWorkItem 回调函数与父设备对象的回调函数同步。
框架等待锁
使用框架等待锁从 IRQL = PASSIVE_LEVEL 运行的代码同步对驱动程序数据的访问。 在驱动程序可以使用框架等待锁之前,它必须调用 WdfWaitLockCreate 来创建等待锁对象。 然后,驱动程序可以调用 WdfWaitLockAcquire 来获取锁,并 调用 WdfWaitLockRelease 来释放它。
框架旋转锁
使用框架旋转锁从 IRQL <= DISPATCH_LEVEL 运行的代码同步对驱动程序数据的访问。 当驱动程序线程获取旋转锁时,系统会将线程的 IRQL 设置为DISPATCH_LEVEL。 当线程释放锁时,系统会将线程的 IRQL 还原到其以前的级别。
如果未使用自动框架同步的驱动程序,则如果上下文空间可写且驱动程序的事件回调函数不止一个访问空间,则可以使用旋转锁来同步对设备对象的上下文空间的访问。
在驱动程序可以使用框架旋转锁之前,它必须调用 WdfSpinLockCreate 来创建旋转锁对象。 然后,驱动程序可以调用 WdfSpinLockAcquire 来获取锁,并 调用 WdfSpinLockRelease 来释放它。
有关旋转锁的示例用法,请参阅 同步已发送请求的取消。
框架中断锁
对于支持 DIRQL 中断处理的中断对象,框架中断锁是旋转锁。 在驱动程序获取中断旋转锁后,驱动程序会在设备的 DIRQL 处执行,直到它释放该锁。 有关使用中断锁的详细信息,请参阅 同步中断代码。
对于支持被动级别处理的中断对象,框架中断锁是等待锁。 驱动程序获取中断等待锁后,驱动程序会在 IRQL = PASSIVE_LEVEL处执行,直到释放该锁。 有关被动级别处理的详细信息,请参阅 支持被动级别中断。