应用程序不能正常退出,导致无法关机,这种情况通常是应用程序在等待一些I/O request to finish. 应用程序访问远程文件时,这种情况的发生更加频繁.

If an application needs to terminate such requests, it should cancel the request. During process termination, the system walks the list of I/O requests for a process and attempts to cancel each one. This paper discusses why drivers need to implement cancellation and timely completion of I/O requests.

通常导致程序不能正常关闭的原因可能如下.
1 驱动 用kernel-mode的等待方式阻塞应用线程. 这样结束进程时投递的APC就不能被执行. 这样进程就不能被正常结束了.

XP 上可以用 Cancel-Safe IRP Queues 来解决这类问题.( IoCsqXxx )
VISTA后可以使用 FltCancellableWaitForSingleObject

原则
1 任何IRP的处理如果要耗费比较长的时间,那它必须支持 cancelled 操作.
2 不要去BLOCK Close-IRPs, 除非是必须的一些场景,而且时间必须很短.
3 所有long-term IRPs的处理必须是pended(驱动返回STATUS_PENDING,这样就不会阻塞当前线程了)的. pended 处理也要支持IRP cancellation;或者支持超时机制.

什么情况下需要支持 IRP Cancellation
1 IRP被QUEUE然后做进一步操作
2 IRP的处理时间比较长或者不明确.

FltCancellableWaitForSingleObject 其实就是对 FsRtlCancellableWaitForMultipleObjects的封装,FsRtlCancellableWaitForMultipleObjects实现的功能跟 KeWaitForMultipleObjects 一样,唯一的不同就是等待的对象是Cancellable, (a wait that can be terminated). 下面为例子:
1) 情景1
线程A触发某个文件打开操作.
|
驱动B 捕获IRP_MJ_CREATE -> 调用 KeWaitForMultipleObjects 阻塞线程 A, 如果 KeWaitForMultipleObjects 不返回,那线程A就一直不能被结束.

1) 情景2
线程A触发某个文件打开操作.
|
驱动B 捕获IRP_MJ_CREATE -> 调用 FltCancellableWaitForSingleObject 阻塞线程 A, 如果 FltCancellableWaitForSingleObject 不返回,那线程A结束了,那FltCancellableWaitForSingleObject 就返回了.

常见的使用方法:
KeInitializeEvent( xxSynchronizationEvent, SynchronizationEvent, TRUE ); //初始化为SynchronizationEvent事件,
(A SynchronizationEvent is also called an autoreset or autoclearing event. When such an event is set, a single waiting thread becomes eligible for execution. The kernel automatically resets the event to the not-signaled state each time a wait is satisfied.)

status = FltCancellableWaitForSingleObject( xxSynchronizationEvent,
NULL,
Data );
开始执行为立刻返回,然后把 xxSynchronizationEvent非信号态. 后面的线程再进来就一直在等待,除非有代码手动调用
KeSetEvent( xxSynchronizationEvent, 0, FALSE ); 把事件设置为信号态.

注: 这种应用其实类似于驱动中的互斥体,只不过被阻塞的线程是可以退出的或者结束的. 这种在驱动做串行操作是很合适的.
比如用STREAM CTX对应一个 xxSynchronizationEvent, 对同一个文件的扫描需要串行进行. 当然也可以用STREAN HANDLE CTX来实现.

【原创】CancellableWait的更多相关文章

  1. 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付

    前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...

  2. 【原创分享·微信支付】C# MVC 微信支付教程系列之现金红包

            微信支付教程系列之现金红包           最近最弄这个微信支付的功能,然后扫码.公众号支付,这些都做了,闲着无聊,就看了看微信支付的其他功能,发现还有一个叫“现金红包”的玩意,想 ...

  3. 【原创分享·微信支付】 C# MVC 微信支付教程系列之扫码支付

    微信支付教程系列之扫码支付                  今天,我们来一起探讨一下这个微信扫码支付.何为扫码支付呢?这里面,扫的码就是二维码了,就是我们经常扫一扫的那种二维码图片,例如,我们自己添 ...

  4. 【原创分享·微信支付】 C# MVC 微信支付教程系列之公众号支付

    微信支付教程系列之公众号支付         今天,我们接着讲微信支付的系列教程,前面,我们讲了这个微信红包和扫码支付.现在,我们讲讲这个公众号支付.公众号支付的应用环境常见的用户通过公众号,然后再通 ...

  5. 【原创分享·微信支付】C# MVC 微信支付之微信模板消息推送

    微信支付之微信模板消息推送                    今天我要跟大家分享的是“模板消息”的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐.原因在哪?就是因为它是依赖微信生存的呀,所以他能不 ...

  6. [原创]java使用JDBC向MySQL数据库批次插入10W条数据测试效率

    使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(100000),如何提高效率呢?在JDBC编程接口中Statement 有两个方法特别值得注意:通过使用addBatch( ...

  7. GJM : C#设计模式汇总整理——导航 【原创】

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  8. 信息安全-5:RSA算法详解(已编程实现)[原创]

    转发注明出处:http://www.cnblogs.com/0zcl/p/6120389.html 背景介绍 1976年以前,所有的加密方法都是同一种模式: (1)甲方选择某一种加密规则,对信息进行加 ...

  9. Atitit.你这些项目不都是模板吗?不是原创  集成和整合的方式大总结

    Atitit.你这些项目不都是模板吗?不是原创  集成和整合的方式大总结 1.1. 乔布斯的名言:创新即整合(Creativity is just connecting things).1 1.2. ...

随机推荐

  1. nodejs入门API之fs模块

    fs模块下的类与FS常量 fs模块下的主要方法 fs的Promise API与FileHandle类 一.fs模块下的类 1.1 fs.Dir:表示目录流的类,由 fs.opendir().fs.op ...

  2. UDP及操作系统理论

    UDP介绍 udp协议又称用户数据报协议 在OSI七层模型中,它于TCP共同存在于传输层 仅用于不要求可靠性,不要求分组顺序且数据较小的简单传输,力求速度 UDP结合socket用法 1.创建sock ...

  3. leetcode-8.atoi · string *

    题面 原题挺长的,还是英文,就不抄了,

  4. 雨后清风U盘启动盘的五大用处及制作方法

    如果有一个U盘可以帮助你安装系统,或者在你的电脑系统崩溃时帮助你修复系统,是不是很方便呢?雨后清风U盘启动盘就能帮你实现这样的效果.除此之外,雨后清风U盘启动盘还有另外一些用处.下面就来和大家分享一下 ...

  5. xtrabackup数据库备份工具

    下来我来介绍一下更强大的备份工具:xtrabackup xtrabackup是Percona公司CTO Vadim参与开发的一款基于InnoDB的在线热备工具,具有开源,免费,支持在线热备,备份恢复速 ...

  6. 如何利用while语句打印“九九乘法口诀表”

    需求:输出九九乘法表 plus.py代码如下: i=1 j=1 while i<=9: j=1 while j<=i: print(j,'*',i,'=',str(i*j)+' ',end ...

  7. PAT Basic 1089 狼人杀-简单版 (20 分)

    以下文字摘自<灵机一动·好玩的数学>:“狼人杀”游戏分为狼人.好人两大阵营.在一局“狼人杀”游戏中,1 号玩家说:“2 号是狼人”,2 号玩家说:“3 号是好人”,3 号玩家说:“4 号是 ...

  8. 深度解析Graph Embedding

    Graph Embedding是推荐系统.计算广告领域最近非常流行的做法,是从word2vec等一路发展而来的Embedding技术的最新延伸:并且已经有很多大厂将Graph Embedding应用于 ...

  9. django考点

    django考点 1 列举Http请求中常见的请求方式2 谈谈你对HTTP协议的认识.1.1 长连接3 简述MVC模式和MVT模式4 简述Django请求生命周期5 简述什么是FBV和CBV6 谈一谈 ...

  10. 2018/7/31-zznu-oj-问题 B: N! 普拉斯 -【求大数的阶乘-ll存不下-然后取尾零的个数输出-暴力模拟】

    问题 B: N! 普拉斯 时间限制: 1 Sec  内存限制: 128 MB提交: 114  解决: 35[提交] [状态] [讨论版] [命题人:admin] 题目描述 在处理阶乘时也需要借助计算器 ...