關於驅動讀寫非同步超時的處理,網路上的資料相對稀少,正好最近在工作上遇到了這個問題,所以就研究了一下,發現還是有些門道的。如果完全按照應用層讀寫超時的處理邏輯來處理驅動層的話就會出現藍屏等問題
只要涉及到讀寫超時,那麼我們第一印象肯定會想到事件和事件等待相關操作與函式的呼叫,那麼我們來看一下驅動的幾個檔案操作函式宣告:
首先是開啟操作
ntstatus zwcreatefile(
_out_ phandle filehandle,
_in_ access_mask desiredaccess,
_in_ pobject_attributes objectattributes,
_out_ pio_status_block iostatusblock,
_in_opt_ plarge_integer allocationsize,
_in_ ulong fileattributes,
_in_ ulong shareaccess,
_in_ ulong createdisposition,
_in_ ulong createoptions,
_in_opt_ pvoid eabuffer,
_in_ ulong ealength
);
根據應用層的經驗,如果要實現超時讀寫,我們需要以非同步的方式開啟檔案,而驅動預設即是非同步開啟操作,如果你需要同步開啟,需要設定下面的值(兩個需要同時設定)
desiredaccess:synchronize
createoptions:file_synchronous_io_nonalert
然後是讀寫函式,兩個類似
ntstatus zwreadfile(
_in_ handle filehandle,
_in_opt_ handle event,
_in_opt_ pio_apc_routine apcroutine,
_in_opt_ pvoid apccontext,
_out_ pio_status_block iostatusblock,
_out_ pvoid buffer,
_in_ ulong length,
_in_opt_ plarge_integer byteoffset,
_in_opt_ pulong key
);ntstatus zwwritefile(
_in_ handle filehandle,
_in_opt_ handle event,
_in_opt_ pio_apc_routine apcroutine,
_in_opt_ pvoid apccontext,
_out_ pio_status_block iostatusblock,
_in_ pvoid buffer,
_in_ ulong length,
_in_opt_ plarge_integer byteoffset,
_in_opt_ pulong key
);
這裡根據應用層的經驗,我們會找關於事件(event)的引數,根據文件宣告,正好第二個引數涉及到了事件,查閱文件後確定該引數可以用於非同步超時等待。這個時候我們需要建立乙個事件,關於驅動中建立事件的函式我們首先會想到keinitializeevent,但是此處需要的是handle型別,所以我們需要使用下面的方法來建立:
zwcreateevent(&g_hevent, generic_all, null, synchronizationevent, false);
然後我們自然想到以zw開頭來搜尋相關的等待函式
status = zwwaitforsingleobject(g_hevent, false, &time);
這個時候如果status返回的是status_timeout,那麼就代表檔案讀寫超時,這時候我們就關閉事件控制代碼和檔案控制代碼然後返回。如果你真的這麼做了,那麼等資料真正的返回的時候,就會出現藍屏問題。
經過分析發現是因為我們在使用zwclose函式關閉控制代碼後,windows並沒有停止對檔案的操作,由於是是非同步的,所以後台仍然在等待資料的返回,如果這時候我們銷毀了資源,但是資料在超時後返回,那麼就會出現 0xc0000005 這種記憶體訪問錯誤藍屏。那麼我們理所當然想到是否有乙個函式用來取消檔案io操作,答案是有的,但是是未文件化函式,函式宣告如下:
typedef
ntstatus
(ntapi *myzwcanceliofile)(
in handle filehandle,
out pio_status_block iostatusblock);
unicode_string funcname = rtl_constant_string(l"zwcanceliofile");
zwcanceliofile = (myzwcanceliofile)mmgetsystemroutineaddress(&funcname);
if (zwcanceliofile == null)
完畢 訊號驅動,超時接收
一 訊號驅動。1 訊號驅動原理是什麼?就是使用了系統程式設計中訊號的機制,首先讓程式安裝sigio的訊號處理函式,通過監聽檔案描述符是否產生了sigio訊號,我們就知道檔案描述符有沒有資料到達。如果有資料到達 小明這個客人來了 則系統就會產生了sigio訊號 門鈴響了 我們只需要在訊號處理函式讀取資...
C 超時處理
在網上搜尋了很多c 超時處理的方法,下面一種是我除錯過的 超時處理 public class timeoutchecker public bool wait long timeout this.dispose return flag private void dispose 呼叫超時處理方法 檢查攝...
php curl 超時處理
php curl處理請求超時 背景 寫了乙個api管理的工具,增加了api請求的的工具,某些介面請求時間比較長,某些介面時間必須要短,希望超過超時時間的請求返回其它的狀態碼,要跟失敗或者curl失敗區分開,本質上雖然都是curl失敗但是從需求角度要區分開,但是php的curl沒有類似事件的一些操作 ...