huoxy
驱动小牛
驱动小牛
  • 注册日期2002-03-01
  • 最后登录2014-02-24
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望4点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:1716回复:6

事件Event什么时候被复位?

楼主#
更多 发布于:2002-07-17 12:59
我阅读了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”这个要求。是不是这样?
好好学习,天天向上,做一个乖宝宝。
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-07-17 13:02
我阅读了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”这个要求。是不是这样?


就题论事:

好象在建立事件是有指明是否,自动置位的。。。。

 :)
[color=red]大头鬼! :P[/color]
Henry
驱动牛犊
驱动牛犊
  • 注册日期2001-04-27
  • 最后登录2011-06-20
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望27点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-07-17 13:47
对于AutoReset的Event在KeWaitFor...函数之后会自动Reset.
驱动人生。
huoxy
驱动小牛
驱动小牛
  • 注册日期2002-03-01
  • 最后登录2014-02-24
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望4点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于: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处理结束的作用。我想这不是我们所希望的。

所以,我觉得应该有一个复位过程。
好好学习,天天向上,做一个乖宝宝。
Henry
驱动牛犊
驱动牛犊
  • 注册日期2001-04-27
  • 最后登录2011-06-20
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望27点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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.


驱动人生。
huoxy
驱动小牛
驱动小牛
  • 注册日期2002-03-01
  • 最后登录2014-02-24
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望4点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
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结束
好好学习,天天向上,做一个乖宝宝。
Henry
驱动牛犊
驱动牛犊
  • 注册日期2001-04-27
  • 最后登录2011-06-20
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望27点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-07-23 14:13
实际上我们所说的正好相反。可惜Windows并没有提供一个函数来Wait Event Nonsignaled.不过你可以试试Mutex.
驱动人生。
游客

返回顶部