亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 漫談兼容內核之十五:windows線程的等待、喚醒機制.txt

?? 漫談系統內核內幕 收集得很辛苦 呵呵 大家快下在吧
?? TXT
?? 第 1 頁 / 共 3 頁
字號:
       
        /* Lock is held, disable Wait Next */
        DPRINT("Lock is held\n");
        CurrentThread->WaitNext = FALSE;
    } else {
        /* Lock not held, acquire it */
        DPRINT("Lock is not held, acquiring\n");
        CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
    }

    /* Start the actual Loop */
    do {
       
        /* Get the current Wait Status */
        WaitStatus = CurrentThread->WaitStatus;
   
        /* Append wait block to the KTHREAD wait block list */
        CurrentThread->WaitBlockList = WaitBlock = &CurrentThread->WaitBlock[0];
          
        /* Get the Current Object */
        CurrentObject = (PDISPATCHER_HEADER)Object;
           
        /* FIXME:
        * Temporary hack until my Object Manager re-write.. . . . . .
        */
        if (CurrentObject->Type == IO_TYPE_FILE) {
            . . . . . .
        }

        /* Check if the Object is Signaled */
        if (KiIsObjectSignaled(CurrentObject, CurrentThread)) {
                   
            /* Just unwait this guy and exit */
            if (CurrentObject->SignalState != MINLONG) {
                   
                /* It has a normal signal state, so unwait it and return */
                KiSatisfyObjectWait(CurrentObject, CurrentThread);
                Status = STATUS_WAIT_0;
                goto WaitDone;
                   
            } else {
                   
                /* Is this a Mutant? */
                if (CurrentObject->Type == MutantObject) {
                       
                    /* According to wasm.ru, we must raise this exception (tested and true) */
                    KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
                    ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
                }
            }
        }
       
        /* Set up the Wait Block */
        WaitBlock->Object = CurrentObject;
        WaitBlock->Thread = CurrentThread;
        WaitBlock->WaitKey = (USHORT)(STATUS_WAIT_0);
        WaitBlock->WaitType = WaitAny;
        WaitBlock->NextWaitBlock = NULL;
                     
        /* Make sure we can satisfy the Alertable request */
        KiCheckAlertability(Alertable, CurrentThread, WaitMode, &Status);
   
        /* Set the Wait Status */
        CurrentThread->WaitStatus = Status;
          
        /* Enable the Timeout Timer if there was any specified */
        if (Timeout != NULL) {
            . . . . . .
        }

        /* Link the Object to this Wait Block */
        InsertTailList(&CurrentObject->WaitListHead, &WaitBlock->WaitListEntry);
       
        /* Handle Kernel Queues */
        if (CurrentThread->Queue) {
                
            DPRINT("Waking Queue\n");
            KiWakeQueue(CurrentThread->Queue);
        }

        /* Block the Thread */
        . . . . . .
        PsBlockThread(&Status, Alertable, WaitMode, (UCHAR)WaitReason);
   
        /* Check if we were executing an APC */
        if (Status != STATUS_KERNEL_APC) {
          
            /* Return Status */
            return Status;
        }
       
        DPRINT("Looping Again\n");
        CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
   
    } while (TRUE);
   
WaitDone:
    /* Release the Lock, we are done */
    . . . . . .
    KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
    return Status;      
}[/code]

    為簡單起見,我們略去了代碼中對于超時(Timeout)的設置,也略去了原作者所加的一大段注釋,說日后還要對代碼進行改寫云云。此外,還略去了當目標對象的類型為IO_TYPE_FILE時的處理,因為我們現在還沒有深入到設備驅動中。
    代碼中首先檢查CurrentThread->WaitNext是否為0,以決定在本次調用中是否需要通過KeAcquireDispatcherDatabaseLock()來“鎖定”線程調度,即禁止因別的原因(例如中斷)而引起的線程調度。注意這里鎖定線程調度是必要的,CurrentThread->WaitNext為TRUE只是說明原來就已經鎖定,不應該再來鎖定了。有關線程調度及其鎖定以后在別的漫談中還會講到。
    然后就是程序的主體了。這是一個do{}while(TRUE)無限循環,這循環一共有3個出口,其中之一與Timeout有關,由于有關的代碼已被略去,在這里已經看不見了。剩下的兩個出口,一個是條件語句“if (KiIsObjectSignaled(CurrentObject, CurrentThread))”里面的“goto WaitDone”,這說明目標對象已經收到“信號”、或者說此前已經“到貨”,所以不需要等待了。比方說,假定調用KeWaitForSingleObject()的目的是接收一個報文,但是這個報文在此之前就已到達了,那當然就不用再睡眠等待,而可以立即就返回。不過在返回之前要通過KiSatisfyObjectWait()把賬銷掉。另一個就是PsBlockThread()后面條件語句“if (Status != STATUS_KERNEL_APC)”里面的返回語句。PsBlockThread()是KeWaitForSingleObject()中最本質的操作。正是這個函數,在一般的情況下,將當前線程置于被阻塞(睡眠)狀態并啟動線程調度,直至當前線程因為所等待的條件得到滿足而被喚醒,才從這個函數返回。但是也有例外,就是因為有APC請求而被警醒,此時被警醒的線程會執行APC函數,執行完以后就立即返回,并把Status的返回值設置成STATUS_KERNEL_APC。在這種情況下當然要再次執行PsBlockThread(),這就是為什么要把PsBlockThread()放在一個循環中的原因。
    再看阻塞當前進程之前的準備工作。這里有兩個重點。一個是對KiIsObjectSignaled()的調用、以及根據其結果作出的反應,這前面已經講過了。另一個是對KiCheckAlertability()的調用。在調用NtWaitForSingleObject()的時候有個參數Alertable,表示是否允許本次等待因APC請求而中斷,或者說“被警醒”。這個參數一路傳了下來。
    如果一個線程的睡眠/等待狀態是“可警醒”的,那么:
?  ● 別的線程可以通過系統調用NtAlertThread()將其警醒。
?  ● APC請求的到來也可以將其警醒。
    讀者也許會想,既然當前線程已經睡眠,這APC請求從何而來呢?其實很簡單。例如,一個線程可能通過系統調用NtWriteFile()啟動了一次異步的文件操作,由于是異步操作,這個系統調用很快就返回了,然后這線程就因為進程間通信而輾轉地進入了KeWaitForSingleObject()、并因此而被阻塞進入了睡眠。然而,這個進程所啟動的異步操作仍在進行,當這異步操作最終完成時,內核會把預定的APC函數掛入這個線程的APC請求隊列。這時候,目標線程的睡眠之是否可警醒,就顯然會有不一樣的效果。這里KiCheckAlertability()的作用是結合參數Alertable的值檢查當前線程是否已經受到警醒,以及是否已經有APC請求,并依此進行必要的狀態設置。
    再看對于KWAIT_BLOCK數據結構的設置,其中的字段WaitType設置成WaitAny,與此相對的是WaitAll。在對于多個對象的等待中,前者表示其中只要有任何一個對象滿足條件即可,后者則表示必須全部滿足條件。不過KeWaitForSingleObject()所等待的是單一對象,所以二者其實并無不同,只是按編程的約定采用WaitAny。另一個字段WaitKey實際上就是當前狀態,STATUS_WAIT_0表示正常的等待。
    接著就通過InsertTailList()把已經準備好的KWAIT_BLOCK數據結構插入目標對象的WaitListHead隊列。這樣,一旦目標對象的狀態發生變化,就可以順著這個隊列找到所有在這個對象上等待的線程。
    下面對CurrentThread->Queue的檢查和對于KiWakeQueue()的調用與設備驅動有關,而不在我們此刻關心的范圍內,所以也把它跳過。
    再往下就是調用PsBlockThread()使當前線程進入睡眠了。

[code][NtWaitForSingleObject() > KeWaitForSingleObject() > PsBlockThread()]

VOID
STDCALL
PsBlockThread(PNTSTATUS Status,
              UCHAR Alertable,
              ULONG WaitMode,
              UCHAR WaitReason)
{
    PKTHREAD Thread = KeGetCurrentThread();
    PKWAIT_BLOCK WaitBlock;

    if (Thread->ApcState.KernelApcPending) {
   
        DPRINT("Dispatching Thread as ready (APC!)\n");
       
        /* Remove Waits */
        WaitBlock = Thread->WaitBlockList;
        while (WaitBlock) {
            RemoveEntryList (&WaitBlock->WaitListEntry);
            WaitBlock = WaitBlock->NextWaitBlock;
        }
        Thread->WaitBlockList = NULL;
       
        /* Dispatch it and return status */
        PsDispatchThreadNoLock (THREAD_STATE_READY);
        if (Status != NULL) *Status = STATUS_KERNEL_APC;

    } else {

        /* Set the Thread Data as Requested */
        DPRINT("Dispatching Thread as blocked\n");
        Thread->Alertable = Alertable;
        Thread->WaitMode = (UCHAR)WaitMode;
        Thread->WaitReason = WaitReason;
       
        /* Dispatch it and return status */
        PsDispatchThreadNoLock(THREAD_STATE_BLOCKED);
        if (Status != NULL) *Status = Thread->WaitStatus;
    }
   
    DPRINT("Releasing Dispatcher Lock\n");
    KfLowerIrql(Thread->WaitIrql);
}[/code]

    這個函數沒有什么特殊之處,值得一說的是它會檢查是否有APC請求在等待執行,如果有的話就退出等待,不進入睡眠了。PsDispatchThreadNoLock()的作用是線程調度,作為參數傳遞給它的THREAD_STATE_READY和THREAD_STATE_BLOCKED分別表示目標線程的新的狀態。THREAD_STATE_READY顯然是“就緒”,也就是不進入睡眠。而THREAD_STATE_BLOCKED當然是“阻塞”、即睡眠。當然,如果進入睡眠的話,那就要到以后被喚醒(所等待的條件得到滿足或超時)或警醒(APC請求的到來或受別的線程警醒)才會從這個函數返回。在這里,我們假定當前進程被阻塞。
    至此,當前線程、即等待“到貨”(進程間信息的到來)的線程已被阻塞進入了睡眠。下面要看的是當進程間信息到來時怎樣喚醒這個線程了。

    在Windows內核中,與KeWaitForSingleObject()相對的函數是KiWaitTest()。前者使一個線程在一個(可等待)對象上等待而被阻塞進入睡眠,后者則喚醒在一個對象上等待的所有線程。

[code]VOID  FASTCALL
KiWaitTest(PDISPATCHER_HEADER Object, KPRIORITY Increment)
{
    PLIST_ENTRY WaitEntry;
    PLIST_ENTRY WaitList;
    PKWAIT_BLOCK CurrentWaitBlock;
    PKWAIT_BLOCK NextWaitBlock;
   
    /* Loop the Wait Entries */
    DPRINT("KiWaitTest for Object: %x\n", Object);
    WaitList = &Object->WaitListHead;
    WaitEntry = WaitList->Flink;
    while ((WaitEntry != WaitList) && (Object->SignalState > 0)) {
       
        /* Get the current wait block */
        CurrentWaitBlock =
                CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
       
        /* Check the current Wait Mode */
        if (CurrentWaitBlock->WaitType == WaitAny) {
       
            /* Easy case, satisfy only this wait */
            DPRINT("Satisfiying a Wait any\n");
            WaitEntry = WaitEntry->Blink;
            KiSatisfyObjectWait(Object, CurrentWaitBlock->Thread);
        } else {
       
            /* Everything must be satisfied */
            DPRINT("Checking for a Wait All\n");
            NextWaitBlock = CurrentWaitBlock->NextWaitBlock;
           
            /* Loop first to make sure they are valid */
            while (NextWaitBlock) {
           
                /* Check if the object is signaled */
                if (!KiIsObjectSignaled(Object, CurrentWaitBlock->Thread)) {
               
                    /* It's not, move to the next one */
                    DPRINT1("One of the object is non-signaled, sorry.\n");
                    goto SkipUnwait;
                }
               
                /* Go to the next Wait block */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品综合一区二区三区| 国产日韩欧美精品一区| 亚洲chinese男男1069| 色婷婷综合久久久| 亚洲电影在线免费观看| 欧美日韩电影一区| 久久激情五月婷婷| 欧美极品xxx| 91蜜桃在线免费视频| 亚洲综合久久久| 日韩欧美成人午夜| 成a人片国产精品| 亚洲成av人片| 久久综合色8888| 99精品国产视频| 亚洲午夜一区二区| 制服.丝袜.亚洲.另类.中文| 国精产品一区一区三区mba视频| 精品国内二区三区| 久久精品免费观看| 久久欧美一区二区| 成人久久18免费网站麻豆 | 免费在线视频一区| 日韩免费高清视频| 国产麻豆精品久久一二三| 国产午夜精品久久久久久免费视| 免费不卡在线视频| 日本一区免费视频| 一本色道久久综合亚洲aⅴ蜜桃| 尤物视频一区二区| 欧美一区二区精品在线| 国产一区二区三区国产| 久久久国产精品麻豆| 成人ar影院免费观看视频| 亚洲精品老司机| 欧美一二三区精品| 成人av中文字幕| 香蕉影视欧美成人| 久久久久亚洲蜜桃| 欧美视频日韩视频在线观看| 麻豆精品视频在线观看视频| 久久久久久久av麻豆果冻| 91丨porny丨在线| 青青草一区二区三区| 久久伊人中文字幕| 精品污污网站免费看| 国产一区二区调教| 一区二区三区毛片| 久久午夜羞羞影院免费观看| av电影在线观看一区| 日韩va欧美va亚洲va久久| 久久精品免视看| 一本一道综合狠狠老| 水野朝阳av一区二区三区| 国产日本欧洲亚洲| 91精品国产一区二区三区香蕉| 国产精品1区二区.| 日韩不卡手机在线v区| 国产精品―色哟哟| 日韩一区二区影院| 色8久久人人97超碰香蕉987| 裸体健美xxxx欧美裸体表演| 亚洲精品五月天| 国产日韩精品一区| 日韩欧美高清一区| 91精品办公室少妇高潮对白| 国产激情精品久久久第一区二区| 亚洲h精品动漫在线观看| 国产精品天美传媒| 久久久久久久久久看片| 欧美日韩国产色站一区二区三区| 成人精品高清在线| 国产一区二区三区综合| 视频在线观看国产精品| 一区二区三区中文字幕在线观看| 国产欧美日韩麻豆91| 欧美xxxx在线观看| 日韩一区二区麻豆国产| 欧美日韩亚洲另类| 成人黄色网址在线观看| 久久国产精品一区二区| 国产精品久久一卡二卡| 日韩欧美国产1| 欧美日韩免费不卡视频一区二区三区| 99免费精品在线观看| 国产成人自拍网| 理论片日本一区| 日韩精品亚洲专区| 亚洲成a人v欧美综合天堂| 国产精品萝li| 国产精品你懂的在线欣赏| 久久久高清一区二区三区| 久久综合九色综合97婷婷女人| 7777精品伊人久久久大香线蕉 | 一本大道久久a久久精二百 | 综合在线观看色| 国产精品久久久久9999吃药| 久久免费的精品国产v∧| 欧美日本一区二区三区四区| www.亚洲精品| av男人天堂一区| 一本色道久久综合亚洲精品按摩| 一本色道久久加勒比精品| 色94色欧美sute亚洲线路一ni| 在线亚洲高清视频| 欧美人与禽zozo性伦| 制服丝袜亚洲精品中文字幕| 日韩三级av在线播放| 精品国产凹凸成av人网站| 久久无码av三级| 中文字幕在线观看一区二区| 中文字幕亚洲在| 亚洲一区二区三区爽爽爽爽爽| 亚洲色图制服诱惑| 国产精品麻豆欧美日韩ww| 亚洲欧美偷拍三级| 午夜精品久久久久久久| 蜜臀av性久久久久蜜臀aⅴ流畅| 久久国产精品免费| 风流少妇一区二区| 色狠狠一区二区三区香蕉| 欧美日韩精品欧美日韩精品一 | 亚洲一级电影视频| 奇米精品一区二区三区在线观看一| 精品综合免费视频观看| av中文字幕亚洲| 欧美日韩亚洲综合| 欧美一区二区大片| 国产人成亚洲第一网站在线播放 | 最新国产の精品合集bt伙计| 一区二区三区四区高清精品免费观看| 婷婷久久综合九色综合绿巨人| 精品一区二区久久| 色狠狠色狠狠综合| 精品va天堂亚洲国产| 亚洲欧洲综合另类| 久久国产综合精品| 欧美主播一区二区三区| www成人在线观看| 亚洲综合男人的天堂| 日精品一区二区| 国产成人啪午夜精品网站男同| 色av成人天堂桃色av| 欧美成人a∨高清免费观看| 国产精品无人区| 天堂蜜桃91精品| 韩国女主播成人在线观看| 九九**精品视频免费播放| av一二三不卡影片| 日韩免费观看高清完整版| 一区二区高清视频在线观看| 视频一区二区欧美| 99re这里只有精品首页| 欧美va亚洲va香蕉在线| 亚洲综合一区二区精品导航| 国产精品自在欧美一区| 制服.丝袜.亚洲.另类.中文 | 亚洲精品视频一区| 国产东北露脸精品视频| 777精品伊人久久久久大香线蕉| 国产精品视频一区二区三区不卡| 日本亚洲一区二区| 日本高清不卡一区| 亚洲国产精品成人久久综合一区| 视频在线观看91| 97久久精品人人做人人爽| 欧美一区二区视频观看视频| 亚洲图片有声小说| 色狠狠桃花综合| 亚洲欧洲国产日韩| 风流少妇一区二区| 国产亚洲1区2区3区| 美国精品在线观看| 日韩欧美的一区| 日本不卡123| 在线91免费看| 日本在线不卡一区| 欧美男生操女生| 午夜精品一区二区三区免费视频 | 亚洲午夜久久久久久久久电影网| av电影天堂一区二区在线 | 欧美xxxx老人做受| 麻豆91免费看| 日韩午夜中文字幕| 激情综合网av| 精品国产一区久久| 国内外成人在线视频| 久久综合网色—综合色88| 极品尤物av久久免费看| 久久夜色精品国产欧美乱极品| 国产一区二区福利| 2024国产精品| 国产乱码精品一区二区三区五月婷| 欧美一级免费大片| 国产精品自拍一区| 国产精品免费视频网站| 99久久免费视频.com| 一区二区三区日韩精品视频| 欧美日韩国产一区二区三区地区| 午夜不卡在线视频|