Chinaunix首页 | 论坛 | 博客
  • 博客访问: 846066
  • 博文数量: 756
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 4980
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:40
文章分类

全部博文(756)

文章存档

2011年(1)

2008年(755)

我的朋友

分类:

2008-10-13 16:11:10

NTSTATUS
STDCALL
KeDelayExecutionThread(KPROCESSOR_MODE WaitMode,
                       BOOLEAN Alertable,
                       PLARGE_INTEGER Interval)
{
    PKWAIT_BLOCK TimerWaitBlock;
    PKTIMER ThreadTimer;
    PKTHREAD CurrentThread = KeGetCurrentThread();
    NTSTATUS Status;

    DPRINT("Entering KeDelayExecutionThread\n");

    /* Check if the lock is already held */
    if (CurrentThread->WaitNext)  {

        /* 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();
    }

    /* Use built-in Wait block */
    TimerWaitBlock = &CurrentThread->WaitBlock[TIMER_WAIT_BLOCK];

    /* Start Wait Loop */
    do {

        /* We are going to wait no matter what (that's the point), so test Alertability */
        if (KiCheckAlertability(Alertable, CurrentThread, WaitMode, &Status))
            break;

        /* Set Timer */
        ThreadTimer = &CurrentThread->Timer;

        /* Setup the Wait Block */
        CurrentThread->WaitBlockList = TimerWaitBlock;
        TimerWaitBlock->Object = (PVOID)ThreadTimer;
        TimerWaitBlock->Thread = CurrentThread;
        TimerWaitBlock->WaitKey = (USHORT)STATUS_TIMEOUT;
        TimerWaitBlock->WaitType = WaitAny;
        TimerWaitBlock->NextWaitBlock = TimerWaitBlock;

        /* Link the timer to this Wait Block */
        InitializeListHead(&ThreadTimer->Header.WaitListHead);
        InsertTailList(&ThreadTimer->Header.WaitListHead, &TimerWaitBlock->WaitListEntry);

        /* Insert the Timer into the Timer Lists and enable it */
        if (!KiInsertTimer(ThreadTimer, *Interval)) {

            /* FIXME: The timer already expired, we should find a new ready thread */
            Status = STATUS_SUCCESS;
            break;
        }

        /* Handle Kernel Queues */
        if (CurrentThread->Queue) {

            DPRINT("Waking Queue\n");
            KiWakeQueue(CurrentThread->Queue);
        }

        /* Block the Thread */
        DPRINT("Blocking the Thread: %d, %d, %x\n", Alertable, WaitMode, KeGetCurrentThread());
        KiBlockThread(&Status,
                      Alertable,
                      WaitMode,
                      DelayExecution);

        /* Check if we were executing an APC or if we timed out */
        if (Status != STATUS_KERNEL_APC) {

            /* This is a good thing */
            if (Status == STATUS_TIMEOUT) Status = STATUS_SUCCESS;

            /* Return Status */
            return Status;
        }

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

    } while (TRUE);

    /* Release the Lock, we are done */
    DPRINT("Returning from KeDelayExecutionThread(), %x. Status: %d\n", KeGetCurrentThread(), Status);
    KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
    return Status;
}


--------------------next---------------------

阅读(503) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~