【原创】CancellableWait
应用程序不能正常退出,导致无法关机,这种情况通常是应用程序在等待一些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的更多相关文章
- 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付
前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...
- 【原创分享·微信支付】C# MVC 微信支付教程系列之现金红包
微信支付教程系列之现金红包 最近最弄这个微信支付的功能,然后扫码.公众号支付,这些都做了,闲着无聊,就看了看微信支付的其他功能,发现还有一个叫“现金红包”的玩意,想 ...
- 【原创分享·微信支付】 C# MVC 微信支付教程系列之扫码支付
微信支付教程系列之扫码支付 今天,我们来一起探讨一下这个微信扫码支付.何为扫码支付呢?这里面,扫的码就是二维码了,就是我们经常扫一扫的那种二维码图片,例如,我们自己添 ...
- 【原创分享·微信支付】 C# MVC 微信支付教程系列之公众号支付
微信支付教程系列之公众号支付 今天,我们接着讲微信支付的系列教程,前面,我们讲了这个微信红包和扫码支付.现在,我们讲讲这个公众号支付.公众号支付的应用环境常见的用户通过公众号,然后再通 ...
- 【原创分享·微信支付】C# MVC 微信支付之微信模板消息推送
微信支付之微信模板消息推送 今天我要跟大家分享的是“模板消息”的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐.原因在哪?就是因为它是依赖微信生存的呀,所以他能不 ...
- [原创]java使用JDBC向MySQL数据库批次插入10W条数据测试效率
使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(100000),如何提高效率呢?在JDBC编程接口中Statement 有两个方法特别值得注意:通过使用addBatch( ...
- GJM : C#设计模式汇总整理——导航 【原创】
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
- 信息安全-5:RSA算法详解(已编程实现)[原创]
转发注明出处:http://www.cnblogs.com/0zcl/p/6120389.html 背景介绍 1976年以前,所有的加密方法都是同一种模式: (1)甲方选择某一种加密规则,对信息进行加 ...
- Atitit.你这些项目不都是模板吗?不是原创 集成和整合的方式大总结
Atitit.你这些项目不都是模板吗?不是原创 集成和整合的方式大总结 1.1. 乔布斯的名言:创新即整合(Creativity is just connecting things).1 1.2. ...
随机推荐
- MySql翻页查询
分页查询在网页中随处可见,那原理是什么呢?下面简单介绍一下基于MySql数据库的limit实现方法. 首先明确为什么要使用分页查询,因为数据庞大,查询不可能全部显示在页面上,如果全部显示在页面上,也会 ...
- kong网关命令(一)
上次在虚拟机里安装kong网关后,因为版本(1.4)太高,目前Kong Dashboard无法支持, 后续发现Git上有个开源工具Kong admin ui,下载源码并部署到NGINX. 但是发现使用 ...
- restTemplate源码解析(五)处理ClientHttpResponse响应对象
所有文章 https://www.cnblogs.com/lay2017/p/11740855.html 正文 上一篇文章中,我们执行了ClientHttpRequest与服务端进行交互.并返回了一个 ...
- 补充:Python安装
需要安装Python2.7.Numpy和Matplotlib.由于Python不支持向下兼容,因此在Python3.×下你一定能正常运行Python2.×的代码.上述模块最简单的安装方法就是用软件包安 ...
- B树Java代码实现以及测试
B树定义 B 树又叫平衡多路查找树.一棵m阶的B 树 (m叉树)的特性如下: 根节点至少有两个孩子 每个非根节点至少有M/2(上取整)个孩子,至多有M个孩子. 每个非根节点至少有M/2-1(上取整)个 ...
- SQL SERVER 查询第20行到30之间的数据
1.先查询前20行的ID,后查询除去20条记录的前10条记录 SELECT TOP * FROM tbBank WHERE BankID NOT IN(SELECT TOP BankID FROM t ...
- Nginx中ngx_http_fastcgi_module
转发请求到 FastCGI 服务器器,不不⽀支持 php 模块⽅方式指令:15.1 fastcgi_pass设置 fastcgi 服务器器的地址.地址可以指定为域名或 IP 地址,以及端⼝口Synta ...
- linux基础知识和常用命令
1.修改主机名 切换到root,然后执行 vim /etc/sysconfig/network,进入其中,更改hostname即可.insert进入修改,esc+:,wq保存退出. 2.用户切换 普通 ...
- email.py
import os import argparse import yaml import smtplib import csv from email.mime.multipart import MIM ...
- hibernate配置和映射文件
映射文件 <?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping ...