阅读:1716回复:6
事件Event什么时候被复位?
我阅读了WinDDK2000附带的BulkUsb例子,其中使用了许多的事件,但是只看到了对置位事件的调用KeSetEvent,而没有复位的调用KeClearEvent or KeResetEvent,(我没写错函数名吧)。
Event有两种,Sync Event and Noti Event,例子使用的事件都是Noti Event,按照帮助的意思,应该显示的调用KeResetEvent or KeClearEvent来复位,但是例子没有调用。我认为这样会出问题,因为如果假设a==0则设置Ev1,但是当a<>1时却没有复位Ev1,那么,如果经历过一次a==0,则以后无论什么时候使用KeWaitSingleObject(函数名忘了),都会立刻返回,因为Ev1已经\"为真\",不知道我的分析是否正确?期待前辈释疑。 另外,即使使用Sync Event,如果已经有一次a==0 -> Ev1=True,然后a<>0(这时Ev1应该依然TRUE),如果这时需要等待 a 再次 == 0 而调用KeWait(Ev1),但是Ev1这时已经=TRUE,这样KeWait会立刻返回,而没有经历a==0,也就是说,没有达到我们的“等待a==0”这个要求。是不是这样? |
|
|
沙发#
发布于:2002-07-17 13:02
我阅读了WinDDK2000附带的BulkUsb例子,其中使用了许多的事件,但是只看到了对置位事件的调用KeSetEvent,而没有复位的调用KeClearEvent or KeResetEvent,(我没写错函数名吧)。 就题论事: 好象在建立事件是有指明是否,自动置位的。。。。 :) |
|
|
板凳#
发布于:2002-07-17 13:47
对于AutoReset的Event在KeWaitFor...函数之后会自动Reset.
|
|
|
地板#
发布于:2002-07-18 09:56
我的疑惑是:KeWait等待一个事件发生,这个事件应该从开始调用KeWait后发生才有效,如果在KeWait调用前,此事件已经设置为Signaled状态,这不是我们所希望的。
比如:我们开始处理一个Irp,这时应该设置NoPendingIoEvent为无效状态,等Irp处理结束后,设置NoPendingIoEvent为Signaled状态。 我觉得应该是这样的,因为假如在\"意外删除\"事件时要使用KeWait(NoPendingIoEvent),而NoPendingIoEvent在第一个Irp结束后就被设置为Signaled状态,以后都始终是Signaled状态(假如在此KeWait前没有其他KeWait),这样调用KeWait时,即使还有一个Irp正在处理,KeWait也立刻返回,因为此时Event为Signaled状态,KeWait没有起到等待所有Irp处理结束的作用。我想这不是我们所希望的。 所以,我觉得应该有一个复位过程。 |
|
|
地下室#
发布于:2002-07-18 14:07
你的疑惑是因为对KeWaitForSingleObject函数的不了解。
KeWaitForSingleObject在等待事件完成之后会自动将事件复位。 对于你所说的IRP_MJ_PNP(IRP_MN_SUPPRISE_REMOVAL)事件, 在开始处理IRP时,设NoIoPendingEvent为Nonsignaled,然后发出IRP,设置完成例程,在完成例程中设置NoIoPendingEvent为Signaled。 基本代码如下: .... IoSetCompletionRoutine(); Status = IoCallDriver(fdo, Irp); if (Status == STATUS_PENDING){ KeWaitForSingleObject(NoIoPendingEvent,...); ----(1) } .... CompletionRoutine(PVOID pContext) { PKEVENT NoIoPendingEvent = (PKEVENT)(pContext); KeSetEvent(NoIoPendingEvent); ----(2) return STATUS_SUCCESS; } 在语句(2)执行完之后,NoIoPendingEvent将会被设置为Signaled. 然后语句(1)返回,并将NoIoPendingEvent设置为Nonsignaled. |
|
|
5楼#
发布于:2002-07-23 12:55
复:Henry
你说的这种情况我能理解,但是这不是我所说的那种情况。 你说的是 IoCallDriver(Irp), keWait(Event), CompleteRoutine() Evenet = Signaled, 而我说的是 开始第一个Irp 结束第一个Irp Event = Signaled 开始第二个Irp 结束第二个Irp Event = Signaled 开始第三个Irp 结束第三个Irp Event = Signaled 开始第四个Irp 在另一个过程中KeWait, 此时Event已经Signaled,所以立刻返回 结束第四个Irp Event = Signaled 但实际上我需要等第四个irp结束 |
|
|
6楼#
发布于:2002-07-23 14:13
实际上我们所说的正好相反。可惜Windows并没有提供一个函数来Wait Event Nonsignaled.不过你可以试试Mutex.
|
|
|