IdleTask 详解

来源:互联网 发布:声场模拟软件 编辑:程序博客网 时间:2024/06/05 00:40

在IdleTask::Initialize内部创建线程IdleTaskThread并启动线程。在IdleTaskThread内部有OSHeap fIdleHeap变量,负责存放IdleTask。
在线程内部:IdleTaskThread::Entry()不断的从队列中取出task元素,然后调用elem->Signal(Task::kIdleEvent)放入到线程池中。

/* * * @APPLE_LICENSE_HEADER_START@ *  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved. *  * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. *  * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. *  * @APPLE_LICENSE_HEADER_END@ * *//*    File:       IdleTask.h    Contains:   IdleTasks are identical to normal tasks (see task.h) with one exception:                    You can schedule them for timeouts. If you call SetIdleTimer                on one, after the time has elapsed the task object will receive an                OS_IDLE event.                     */#ifndef _IDLETASK_H_#define _IDLETASK_H_#include "Task.h"#include "OSThread.h"#include "OSHeap.h"#include "OSMutex.h"#include "OSCond.h"class IdleTask;//merely a private implementation detail of IdleTaskclass IdleTaskThread : private OSThread{private:    IdleTaskThread() : OSThread(), fHeapMutex() {}    virtual ~IdleTaskThread() { Assert(fIdleHeap.CurrentHeapSize() == 0); }//私有成员,直供IdleTask调用    void SetIdleTimer(IdleTask *idleObj, SInt64 msec);    void CancelTimeout(IdleTask *idleObj);        virtual void Entry();    OSHeap  fIdleHeap;    OSMutex fHeapMutex;    OSCond  fHeapCond;    friend class IdleTask;};class IdleTask : public Task{public:    //Call Initialize before using this class//创建线程IdleTaskThread并启动线程    static void Initialize();        IdleTask() : Task(), fIdleElem() { this->SetTaskName("IdleTask"); fIdleElem.SetEnclosingObject(this); }        //This object does a "best effort" of making sure a timeout isn't    //pending for an object being deleted. In other words, if there is    //a timeout pending, and the destructor is called, things will get cleaned    //up. But callers must ensure that SetIdleTimer isn't called at the same    //time as the destructor, or all hell will break loose.    virtual ~IdleTask();        //SetIdleTimer:    //This object will receive an OS_IDLE event in the following number of milliseconds.    //Only one timeout can be outstanding, if there is already a timeout scheduled, this    //does nothing.//添加到线程的堆中    void SetIdleTimer(SInt64 msec) { sIdleThread->SetIdleTimer(this, msec); }    //CancelTimeout    //If there is a pending timeout for this object, this function cancels it.    //If there is no pending timeout, this function does nothing.    //Currently not supported because OSHeap doesn't support random remove//从线程堆中删除    void CancelTimeout() { sIdleThread->CancelTimeout(this); }private:    OSHeapElem fIdleElem;    //there is only one idle thread shared by all idle tasks.    static IdleTaskThread*  sIdleThread;        friend class IdleTaskThread;};#endif

/* * * @APPLE_LICENSE_HEADER_START@ *  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved. *  * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. *  * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. *  * @APPLE_LICENSE_HEADER_END@ * *//*    File:       IdleTask.cpp    Contains:   IdleTasks are identical to normal tasks (see task.h) with one exception:                    You can schedule them for timeouts. If you call SetIdleTimer                on one, after the time has elapsed the task object will receive an                OS_IDLE event.                     */#include "IdleTask.h"#include "OSMemory.h"#include "OS.h"//IDLETASKTHREAD IMPLEMENTATION:IdleTaskThread*     IdleTask::sIdleThread = NULL;void IdleTaskThread::SetIdleTimer(IdleTask *activeObj, SInt64 msec){    //note: OSHeap doesn't support a random remove, so this function    //won't change the timeout value if there is already one set    if (activeObj->fIdleElem.IsMemberOfAnyHeap())        return;    activeObj->fIdleElem.SetValue(OS::Milliseconds() + msec);        {        OSMutexLocker locker(&fHeapMutex);        fIdleHeap.Insert(&activeObj->fIdleElem);    }    fHeapCond.Signal();}void IdleTaskThread::CancelTimeout(IdleTask* idleObj){    Assert(idleObj != NULL);    OSMutexLocker locker(&fHeapMutex);    fIdleHeap.Remove(&idleObj->fIdleElem);  }voidIdleTaskThread::Entry(){    OSMutexLocker locker(&fHeapMutex);        while (true)    {        //if there are no events to process, block.        if (fIdleHeap.CurrentHeapSize() == 0)            fHeapCond.Wait(&fHeapMutex);        SInt64 msec = OS::Milliseconds();                //pop elements out of the heap as long as their timeout time has arrived        while ((fIdleHeap.CurrentHeapSize() > 0) && (fIdleHeap.PeekMin()->GetValue() <= msec))        {            IdleTask* elem = (IdleTask*)fIdleHeap.ExtractMin()->GetEnclosingObject();            Assert(elem != NULL);            elem->Signal(Task::kIdleEvent);        }                                //we are done sending idle events. If there is a lowest tick count, then        //we need to sleep until that time.        if (fIdleHeap.CurrentHeapSize() > 0)        {            SInt64 timeoutTime = fIdleHeap.PeekMin()->GetValue();            //because sleep takes a 32 bit number            timeoutTime -= msec;            Assert(timeoutTime > 0);            UInt32 smallTime = (UInt32)timeoutTime;            fHeapCond.Wait(&fHeapMutex, smallTime);        }    }   }void IdleTask::Initialize(){    if (sIdleThread == NULL)    {        sIdleThread = NEW IdleTaskThread();        sIdleThread->Start();    }}IdleTask::~IdleTask(){    //clean up stuff used by idle thread routines    Assert(sIdleThread != NULL);        OSMutexLocker locker(&sIdleThread->fHeapMutex);    //Check to see if there is a pending timeout. If so, get this object    //out of the heap    if (fIdleElem.IsMemberOfAnyHeap())        sIdleThread->CancelTimeout(this);}



0 0
原创粉丝点击