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

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

??

?? 兼容內核漫談 適合想將Windows上的程序移植到其它平臺上的朋友研究查看
??
?? 第 1 頁 / 共 5 頁
字號:
    /* Check for Success and release if such */
    if(NT_SUCCESS(Status)) {
       
        LONG Prev;
       
        /* Save the Old State */
        DPRINT("Releasing Mutant\n");
        Prev = KeReleaseMutant(Mutant, MUTANT_INCREMENT, FALSE, FALSE);
        ObDereferenceObject(Mutant);

        /* Return it */       
        if(PreviousCount) {
            _SEH_TRY . . . . . . _SEH_END;
        }
    }
    /* Return Status */
    return Status;
}[/code]
    顯然,這里實質性的操作是KeReleaseMutant(),我們順著往下看。

[code][NtReleaseMutant() > KeReleaseMutant()]

LONG
STDCALL
KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment,
                IN BOOLEAN Abandon, IN BOOLEAN Wait)
{
    KIRQL OldIrql;
    LONG PreviousState;
    PKTHREAD CurrentThread = KeGetCurrentThread();
   
    /* Lock the Dispatcher Database */
    OldIrql = KeAcquireDispatcherDatabaseLock();
   
    /* Save the Previous State */
    PreviousState = Mutant->Header.SignalState;
   
    /* Check if it is to be abandonned */
    if (Abandon == FALSE) {
        /* Make sure that the Owner Thread is the current Thread */
        if (Mutant->OwnerThread != CurrentThread) {
            DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n");
            ExRaiseStatus(STATUS_MUTANT_NOT_OWNED);
        }
        /* If the thread owns it, then increase the signal state */
        Mutant->Header.SignalState++;
    } else  {
        /* It's going to be abandonned */
        DPRINT("Abandonning the Mutant\n");
        Mutant->Header.SignalState = 1;
        Mutant->Abandoned = TRUE;
    }
   
    /* Check if the signal state is only single */
    if (Mutant->Header.SignalState == 1) {
        if (PreviousState <= 0) {
            DPRINT("Removing Mutant\n");
            RemoveEntryList(&Mutant->MutantListEntry);
        }
        /* Remove the Owning Thread and wake it */
        Mutant->OwnerThread = NULL;
        /* Check if the Wait List isn't empty */
        DPRINT("Checking whether to wake the Mutant\n");
        if (!IsListEmpty(&Mutant->Header.WaitListHead)) {
            /* Wake the Mutant */
            DPRINT("Waking the Mutant\n");
            KiWaitTest(&Mutant->Header, Increment);
        }
    }

    /* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */
    if (Wait == FALSE) {
        /* Release the Lock */
        KeReleaseDispatcherDatabaseLock(OldIrql);
    } else {
        /* Set a wait */
        CurrentThread->WaitNext = TRUE;
        CurrentThread->WaitIrql = OldIrql;
    }
    /* Return the previous state */
    return PreviousState;
}[/code]
    參數Abandon表示在退出臨界區以后是否要廢棄這個互斥門。我們從NtReleaseMutant()的代碼中可以看出,實際傳下來的參數值是FALSE。那么什么情況下這個參數會是TRUE呢?據“Native API”書中說,這發生于互斥門的業主、就是已經通過這個互斥門進入了臨界區的線程突然要結束其生命的時候。
    既然臨界區中的線程要退出,這個互斥門就變成無主的了,所以把Mutant->OwnerThread設置成NULL。其余的代碼就留給讀者自己去理解了。

4. 事件(Event)

    信號量機制的另一個變種是“事件”,這是通過事件對象實現的。Windows為事件對象的創建和打開提供了NtCreateEvent()和NtOpenEvent()兩個系統調用。由于所有此類函數的相似性,這兩個系統調用的代碼就不用看了,只要知道內核中代表著事件對象的數據結構是KEVENT就可以了:

[code]typedef struct _KEVENT {
  DISPATCHER_HEADER  Header;
} KEVENT, *PKEVENT, *RESTRICTED_POINTER PRKEVENT;[/code]

    這就是說,除DISPATCHER_HEADER以外,KEVENT就不需要有別的什么字段了。
    Windows定義和提供了兩種不同類型的事件,每個事件對象也因此而分成兩種類型,這就是:

[code]typedef enum _EVENT_TYPE {
  NotificationEvent,
  SynchronizationEvent
} EVENT_TYPE;[/code]
    事件對象的類型是在創建的時候(通過參數)設定的,記錄在對象頭部的Type字段中,設定以后就不能改變。為不同的應用和目的需要使用不同類型的事件對象。
    類型為NotificationEvent的事件代表著“通知”。通知是廣播式的,其作用就是通知公眾某個事件業已發生(Header中的SignalState為1),一個觀看者看了這個布告并不影響別的觀看者繼續觀看。所以,在通知型事件對象上的P操作并不消耗資源,也就是不改變其數值。在這一點上它就像是一個全局(跨進程)的變量。但是,如果事件尚未發生(SignalState為0),則所有的觀看者、即對此對象執行P操作的線程全都被阻塞而進入睡眠,直到該事件發生,在這一點上又不太像“通知”,而反倒是起著同步的作用了(設想你去看高考發榜,但是還沒貼出來,你就被“套住”等在那兒了)。讀者也許會想到,既然P操作不改變SignalState的值,那豈不是一旦SignalState變成1就永遠是1、從而事件對象只能一次性使用了?這確實是個問題,所以Windows又專門提供了一個系統調用NtResetEvent(),用來“重啟(Reset)”一個事件對象、即將其SignalState清0。
    類型為SynchronizationEvent的事件對象則用于同步,這就相當于初值為0、最大值為1的信號量。對于同步型的事件對象,一次P操作相當于消耗一個籌碼(通行證),而V操作則相當于提供一個籌碼。
    回顧一下前面KiIsObjectSignaled()的代碼,這是P操作中用來判斷是否可以(拿到籌碼)進入臨界區的函數。這個函數對于除互斥門以外的所有對象都返回(!Object->SignalState <= 0)。這就是說,不管是同步型還是通知型的事件對象,執行P操作的線程能拿到籌碼或看到通知的條件都是SignalState為1,否則就要睡眠等待。
    再回顧一下KiSatisfyObjectWait()的代碼,這是P操作中拿到籌碼以后的操作:

[code]KiSatisfyObjectWait(PDISPATCHER_HEADER Object, PKTHREAD Thread)
{
    /* Special case for Mutants */
    if (Object->Type == MutantObject) {
        . . . . . .
    } else if ((Object->Type & TIMER_OR_EVENT_TYPE) == EventSynchronizationObject) {
        /* These guys (Syncronization Timers and Events) just get un-signaled */
        Object->SignalState = 0;
    } else if (Object->Type == SemaphoreObject) {
        /* These ones can have multiple signalings, so we only decrease it */
        Object->SignalState--;
    }
}[/code]

    這里Object->Type的最低3位記錄著對象的類型,如果是EventSynchronizationObject就說明是同步型的事件對象,此時把Object->SignalState置0,表示把籌碼消耗掉了。由于事件對象的SignalState只有兩個值0或非0,因而在SignalState為1的條件下將其設置成0跟使之遞減是等價的。可是,如果是通知型的事件對象,那就沒有任何操作,所以并沒有把通知“消耗”掉。所以,這又是變相的P操作。
    跟信號量和互斥門一樣,對事件對象的P操作就是系統調用NtWaitForSingleObject()或NtWaitForMultipleObjects(),或者(如果從內核中調用)也可以是KeWaitForSingleObject(),而KiIsObjectSignaled()和KiSatisfyObjectWait()都是在P操作內部調用的函數。

    事件對象的V操作是系統調用NtSetEvent(),意思是把事件對象的SignalState設置成1。就像NtReleaseMutant()的主體是KeReleaseMutant()一樣,NtSetEvent()的主體是KeSetEvent()。我們跳過NtSetEvent()這一層,直接看KeSetEvent()的代碼。

[code][NtSetEvent() > KeSetEvent()]

LONG  STDCALL
KeSetEvent(PKEVENT Event, KPRIORITY Increment, BOOLEAN Wait)
{
    . . . . . .
    /* Lock the Dispathcer Database */
    OldIrql = KeAcquireDispatcherDatabaseLock();
    /* Save the Previous State */
    PreviousState = Event->Header.SignalState;
   
    /* Check if we have stuff in the Wait Queue */
    if (IsListEmpty(&Event->Header.WaitListHead)) {
        /* Set the Event to Signaled */
        DPRINT("Empty Wait Queue, Signal the Event\n");
        Event->Header.SignalState = 1;
    } else {
        /* Get the Wait Block */
        WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
                                            KWAIT_BLOCK, WaitListEntry);
        /* Check the type of event */
        if (Event->Header.Type == NotificationEvent || WaitBlock->WaitType == WaitAll) {
            if (PreviousState == 0) {
                /* We must do a full wait satisfaction */
                DPRINT("Notification Event or WaitAll, Wait on the Event and Signal\n");
                Event->Header.SignalState = 1;
                KiWaitTest(&Event->Header, Increment);
            }
        } else {
           /* We can satisfy wait simply by waking the thread, since our signal state is 0 now */
            DPRINT("WaitAny or Sync Event, just unwait the thread\n");
            KiAbortWaitThread(WaitBlock->Thread, WaitBlock->WaitKey, Increment);
        }
    }
   
    /* Check what wait state was requested */
    if (Wait == FALSE) {
        /* Wait not requested, release Dispatcher Database and return */   

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩天堂在线观看| 成人午夜视频网站| 亚洲制服丝袜av| 中文字幕第一区二区| 国产午夜精品理论片a级大结局 | 欧美国产一区二区| 精品88久久久久88久久久| 欧美一个色资源| 欧美刺激脚交jootjob| 日韩欧美激情在线| 精品久久久久久久久久久久久久久| 欧美日韩一区精品| 日韩一区二区三区免费观看| 日韩一区二区在线看| 欧美一级欧美三级在线观看| 日韩一区二区中文字幕| 久久夜色精品国产欧美乱极品| 精品日韩一区二区| 国产欧美精品一区二区三区四区| 中文字幕av资源一区| 亚洲日本电影在线| 婷婷中文字幕一区三区| 美女性感视频久久| 丁香亚洲综合激情啪啪综合| 99在线精品一区二区三区| 欧美图区在线视频| 精品日韩欧美在线| 亚洲四区在线观看| 美女一区二区三区| 成人av在线一区二区| 欧美丝袜第三区| 久久免费视频色| 亚洲主播在线播放| 国产在线一区观看| 色婷婷精品大在线视频 | 人人狠狠综合久久亚洲| 国内外成人在线| 色综合一区二区三区| 欧美一级艳片视频免费观看| 久久精品一区四区| 亚洲国产成人av网| 国产在线精品一区二区夜色| jlzzjlzz国产精品久久| 精品视频123区在线观看| 精品毛片乱码1区2区3区| 亚洲欧美日韩小说| 韩国欧美一区二区| 在线一区二区三区做爰视频网站| 欧美一级高清片在线观看| 亚洲国产精品精华液ab| 亚洲狠狠爱一区二区三区| 国产酒店精品激情| 3751色影院一区二区三区| 国产精品色呦呦| 老汉av免费一区二区三区 | 欧美性三三影院| 国产日韩亚洲欧美综合| 日本欧美一区二区| 欧美羞羞免费网站| 国产精品动漫网站| 国产成人精品影院| 日韩一区二区免费视频| 又紧又大又爽精品一区二区| 国产激情一区二区三区| 日韩欧美三级在线| 日韩精品电影一区亚洲| 日本黄色一区二区| 亚洲日本乱码在线观看| 成人黄色大片在线观看| 精品国产欧美一区二区| 日韩电影免费在线看| 在线中文字幕不卡| 亚洲精品国产a| 色香色香欲天天天影视综合网| 欧美激情综合在线| 国产成人在线看| 久久久亚洲国产美女国产盗摄 | 日本一区二区综合亚洲| 精品一区二区三区免费播放| 欧美一区二区三区免费在线看| 亚洲国产成人精品视频| 久久久久国产精品人| 青草国产精品久久久久久| 欧美肥妇毛茸茸| 全国精品久久少妇| 2019国产精品| 成人性生交大合| 亚洲欧美乱综合| 欧美四级电影网| 日韩影视精彩在线| 日韩精品一区二区三区视频| 久久99精品网久久| 国产目拍亚洲精品99久久精品| 成人性生交大合| 亚洲午夜久久久久久久久久久| 色婷婷久久久久swag精品| 一区二区三区四区视频精品免费 | eeuss鲁片一区二区三区| 中文欧美字幕免费| 色综合久久99| 午夜电影久久久| 久久天天做天天爱综合色| 成人综合婷婷国产精品久久蜜臀| 国产精品毛片无遮挡高清| 色偷偷一区二区三区| 婷婷久久综合九色综合伊人色| 日韩午夜精品视频| 成人妖精视频yjsp地址| 亚洲国产精品综合小说图片区| 欧美一区二区三区影视| 国产91精品在线观看| 一区二区三区中文字幕精品精品| 91精品国产综合久久蜜臀| 国产在线国偷精品免费看| 亚洲女性喷水在线观看一区| 91精品国产91热久久久做人人| 国产精品一区二区久久不卡| 一区二区三区不卡在线观看| 日韩免费观看高清完整版在线观看| 丰满亚洲少妇av| 日韩制服丝袜先锋影音| 亚洲日本青草视频在线怡红院| 日韩视频一区在线观看| 91极品美女在线| 国产成人午夜高潮毛片| 日韩av中文字幕一区二区三区| 国产精品国产成人国产三级 | 国产欧美一区视频| 91精品麻豆日日躁夜夜躁| eeuss鲁片一区二区三区| 奇米综合一区二区三区精品视频 | 一区二区三区四区中文字幕| 久久久亚洲综合| 精品成人一区二区三区四区| av成人免费在线观看| 蜜臀精品一区二区三区在线观看| 日韩欧美在线网站| 色婷婷av久久久久久久| 麻豆精品视频在线观看视频| 亚洲国产wwwccc36天堂| 久久久精品人体av艺术| 91福利在线看| 国产98色在线|日韩| 视频一区二区三区中文字幕| 欧美国产精品v| 欧美一级精品在线| 色狠狠桃花综合| 国产不卡在线播放| 国产成人精品三级| 日韩国产欧美一区二区三区| 亚洲欧美在线aaa| 久久综合九色综合97_久久久| 欧美日韩精品一区视频| 99re66热这里只有精品3直播| 国内精品视频666| 麻豆精品视频在线观看视频| 亚洲第一成人在线| 2021国产精品久久精品| 欧美疯狂性受xxxxx喷水图片| 色999日韩国产欧美一区二区| 91蜜桃网址入口| 99久久伊人精品| 国产精品 日产精品 欧美精品| 全部av―极品视觉盛宴亚洲| 天天色综合天天| 五月婷婷综合网| 亚洲成人av一区二区三区| 国产午夜精品一区二区三区四区| 中文字幕av一区二区三区高| 精品sm在线观看| 欧美sm美女调教| 欧美电视剧在线看免费| 国产日韩高清在线| 国产亚洲欧美日韩在线一区| 欧美精品一区二区精品网| 日韩视频中午一区| 久久久精品国产免费观看同学| 2020日本不卡一区二区视频| 日韩欧美一二三| 色婷婷久久一区二区三区麻豆| 欧美日本在线看| 91精品福利在线一区二区三区 | 成人免费毛片aaaaa**| 精品一区二区三区的国产在线播放| 日本视频中文字幕一区二区三区| 日韩成人精品视频| 成人黄色777网| 欧洲一区二区三区免费视频| 欧美日本一区二区三区四区| 色久综合一二码| 久久综合狠狠综合久久综合88| 久久亚洲精品小早川怜子| 欧美国产欧美亚州国产日韩mv天天看完整 | 成人一道本在线| 91在线高清观看| 大桥未久av一区二区三区中文| 欧美午夜一区二区| 亚洲精品一区二区三区香蕉| 国产精品免费丝袜| 久久不见久久见免费视频7|