视窗驱动程序,旋转锁采集和条件测试
Windows driver, spin lock acquisition and condition test
在一个调度例程中,我们有以下代码:
if (DeviceExtension->Flag)
{
KeAcquireInStackQueuedSpinLockAtDpcLevel(&DeviceExtension->SpinLock, &LockHandle);
//... when we will enter here, DeviceExtension->Flag can already be set to FALSE.
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
}
在另一个调度例程中,我们有以下代码:
KeAcquireInStackQueuedSpinLockAtDpcLevel(&DeviceExtension->SpinLock, &LockHandle);
//...
DeviceExtension->Flag = FALSE;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
因此,当我们在第一个调度例程中获取自旋锁时,DeviceExtension->Flag
已经可以通过第二个例程设置为FALSE
。解决方案是获取旋转锁,然后检查DeviceExtension->Flag
。但是DeviceExtension->Flag
可能是 FALSE,在这种情况下,旋转锁获取似乎非常繁重。
我不是很熟悉多线程,尤其是在内核模式下。我知道这个问题很愚蠢,但我迷路了。在这种情况下,正确的解决方案是什么?谢谢。
此标志表示要删除设备,因此它单向工作
对于这个特殊的存在 破损保护
您需要在设备扩展中拥有EX_RUNDOWN_REF RunRef;
成员,而不是bool Flag
初始化它
ExInitializeRundownProtection(&RunRef);
当您需要执行某些操作时,仅当设备尚未删除时,您才需要执行以下操作:
if (ExAcquireRundownProtection(&DeviceExtension->RunRef))
{
// do something
ExReleaseRundownProtection(&DeviceExtension->RunRef)
}
在IRP_MN_REMOVE_DEVICE
处理程序中,您需要调用
ExWaitForRundownProtectionRelease(&DeviceExtension->RunRef);
和重要的说明 - 尽管在 MSDN 中声明必须调用ExAcquireRundownProtection
和ExReleaseRundownProtection
IRQL <= APC_LEVEL
这是错误的和错误的。ExAcquireRundownProtection
简单地对内存执行一些联锁操作,RunRef
到哪个点 - 所以如果它在非页面缓冲池中 - 我们可以随时调用此例程IRQL
.设备扩展位于非页面缓冲池中。ExReleaseRundownProtection
可以额外呼叫KeSetEvent
与等待设置为FALSE
。因此,它可以在IRQL <= DISPATCH_LEVEL
.ExReleaseRundownProtection
我们通常从IoCompletion
例程(以小于或等于DISPATCH_LEVEL
IRQL
执行)调用,所以这里一切都好。
ExWaitForRundownProtectionRelease
当然必须在<= APC_LEVEL
调用,因为在这里我们可以等待,但是 PnP 经理在IRQL
PASSIVE_LEVEL
发送IRP_MN_REMOVE_DEVICE
- 所以这里再次一切正常
当然,您在这里可以使用和删除锁,其功能几乎与破损保护完全相同。 简单的破损保护 - 更多新的 API,以及更好的设计/实现 比较删除锁。 但是,在IoReleaseRemoveLock
和IoReleaseRemoveLock
的文档中正确地指出,IRQL
<= DISPATCH_LEVEL
必须是,并且必须在PASSIVE_LEVEL
调用IoReleaseRemoveLockAndWait
- 如何在for循环中包含两个索引值的测试条件
- 如何在多个 Catch2 测试用例中检查相同的条件
- 这个循环测试条件是什么意思?
- 如果前一个测试条件成功,则禁用测试条件
- 获取模拟开罗::上下文以测试路径上的条件
- 为什么每次迭代都由 i+6 完成,为什么这个素数测试函数的条件是 i*i<=n?
- 视窗驱动程序,旋转锁采集和条件测试
- 无法理解循环中的测试条件
- 返回语句中的条件测试
- 在 for 循环中重新排序测试条件:编译器错误?
- 为什么测试条件没有效果
- C++ - 测试是否存在 DLL 以有条件地运行某些函数
- 使用字符指针测试条件
- 使用 iStream 对象测试条件
- 是否可以将多个关系表达式放入 for 循环的测试条件中
- 具有大量相互依赖条件的单元测试代码
- 如何放置条件断点来测试CString变量是否为空
- c++在while条件下声明和测试变量
- 使用 gtest 测试构造函数内部条件的方法是什么?
- 单元测试的条件派生