现在的位置: 首页 > 综合 > 正文

WaitForSingleObject 的内部实现原理

2013年09月01日 ⁄ 综合 ⁄ 共 1887字 ⁄ 字号 评论关闭

WaitForSingleObject 是 kernel32.dll 的导出函数,WaitForSingleObject 调用了ntdll.dll 的 NtWaitForSingleObject. 
NtWaitForSingleObject 又调用了 KeWaitForSingleObject 

WaitForSingleObject -> NtWaitForSingleObject -> KeWaitForSingleObject 

以下是KeWaitForSingleObject的部分实现代码。

do 
{ 
        WaitStatus = CurrentThread->WaitStatus; 
        CurrentThread->WaitBlockList = WaitBlock = &CurrentThread->WaitBlock[0]; 
        CurrentObject = (PDISPATCHER_HEADER)Object; 

        if (KiIsObjectSignaled(CurrentObject, CurrentThread)) 
        { 
                if (CurrentObject->SignalState != MINLONG) 
                { 
                        KiSatisfyObjectWait(CurrentObject, CurrentThread); 
                        Status = STATUS_WAIT_0; 
                        goto WaitDone; 
                } 
                else 
                { 
                        if (CurrentObject->Type == MutantObject) 
                        { 
                                KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); 
                                ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED); 
                        } 
                } 
        } 

        WaitBlock->Object = CurrentObject; 
        WaitBlock->Thread = CurrentThread; 
        WaitBlock->WaitKey = (USHORT)(STATUS_WAIT_0); 
        WaitBlock->WaitType = WaitAny; 
        WaitBlock->NextWaitBlock = NULL; 

        KiCheckAlertability(Alertable, CurrentThread, WaitMode, &Status); 

        CurrentThread->WaitStatus = Status; 

        if (Timeout != NULL) 
        { 
                //略.有超时设置的情况 
        } 

        InsertTailList(&CurrentObject->WaitListHead, &WaitBlock->WaitListEntry); 

        if (CurrentThread->Queue) 
        { 
                DPRINT("Waking Queue/n"); 
                KiWakeQueue(CurrentThread->Queue); 
        } 

        PsBlockThread(&Status, Alertable, WaitMode, (UCHAR)WaitReason); 

        if (Status != STATUS_KERNEL_APC) 
        { 
                return Status; 
        } 

        DPRINT("Looping Again/n"); 
        CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock(); 

}while (TRUE); 

WaitDone:

    转载自: http://www.vbgood.com/viewthread.php?tid=76711

抱歉!评论已关闭.