⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wartimer.cpp

📁 ftpserver very good sample
💻 CPP
字号:
#include "StdAfx.h"#include "WarTimer.h"   // class implemented#ifndef WAR_AUTO_LOCK_H#   include "WarAutoLock.h"#endif#ifndef WAR_SHUTDOWN_ENGINE_H#   include "WarShutdownEngine.h"#endif#ifndef WAR_LOG#   include "WarLog.h"#endif#ifndef WAR_TIMER_EVENT_TASK_H#   include "WarTimerEventTask.h"#endif#define AUTO_LOCK WarAutoLock MyLock(mLock);/////////////////////////////// PUBLIC ///////////////////////////////////////WarTimer *WarTimer::spThis = NULL;//============================= LIFECYCLE ====================================WarTimer::WarTimer(): mSignal(true){    mPool.Create(5,10);    if (!spThis)        spThis = this;}// WarTimerWarTimer::~WarTimer(){    if (spThis == this)        spThis = NULL;}// ~WarTimer//============================= OPERATORS ====================================//============================= OPERATIONS ===================================void WarTimer::OnShutdown(war_cptr_t ptr){    WarLog sys_log(WARLOG_SYSTEM, "WarTimer::OnShutdown()");    sys_log << "Shutting down the internal timer." << war_endl;    ((WarTimer *)ptr)->SetExitFlag();    while(WarTimer::IsTimerActive())    {        ((WarTimer *)ptr)->mSignal.Signal();        WarTime::Sleep(100);    }}void WarTimer::AddEvent(war_timer_event_ptr_t& newEvent)throw(WarException){    assert(this != NULL); // Must start the timer!    AUTO_LOCK    if (!IsActive())        WarThrow(WarError(WAR_ERR_ABORT_THREAD), NULL);    events_t::const_iterator P = mEvents.insert(newEvent);    if (P == mEvents.begin())    {        // Signal the timer-thread so that it can wake up and         // process the event.        mSignal.Signal();    }}void WarTimer::KillEvent(war_timer_event_ptr_t& oldEvent)throw(WarException){    AUTO_LOCK        for(events_t::iterator P = mEvents.begin()        ; P != mEvents.end()        ; ++P)    {        if (P->IsSameObject(oldEvent))        {            if (P == mEvents.begin())            {                // Signal the timer-thread so that it can wake up and                 // reschedule the next event                mSignal.Signal();            }                        (*P)->Kill();            mEvents.erase(P);            break;        }    }}void WarTimer::SetExitFlag(){    AUTO_LOCK    WarThread::SetExitFlag();    mSignal.Signal();}//============================= ACCESS     ===================================WarTimer& WarTimer::GetTimer() throw(WarException){    if (NULL == spThis)        WarThrow(WarError(WAR_ERR_INTERNAL_DATA_NOT_INITIALIZED), NULL);    return *spThis;}//============================= INQUIRY    ===================================/////////////////////////////// PROTECTED  ///////////////////////////////////void WarTimer::Run(){    WarLog log_error(WARLOG_ERROR, "WarTimer::Run()");    WarLog thrd_log(WARLOG_THREADS, "WarTimer::Run()");    WarShutdownEngine::GetEngine().AddEvent(OnShutdown, this);    war_time_t next_time;    war_timer_event_ptr_t my_event;    thrd_log << "Timer is running"         << war_endl;    SetState(STATE_IDLE);    while(!IsExiting())    {        SetState(STATE_BUSY);        next_time = WarThreadEvent::WAIT_INFINITE;        my_event = NULL;        {            AUTO_LOCK            if (!mEvents.empty())            {                next_time = (*mEvents.begin())->GetTime().GetTimeDiff();                if (next_time > 0)                    goto sleep; // Unlock                my_event = (*mEvents.begin());                mEvents.erase(mEvents.begin());                goto process_it; // Unlock            }        }sleep:        assert(my_event.IsEmpty());        SetState(STATE_IDLE);        mSignal.WaitForEvent(next_time);        continue;process_it:        assert(my_event.IsEmpty() == false);        WarTimerEvent& revent = *my_event;        try        {            if (thrd_log)            {                thrd_log << "Timer is processing event: "                     << revent.Explain();            }            if (revent.IsFast())            {                // Do it now.                 revent.DoTimer();                OnCompleted(my_event);            }            else // Add to queue, another thread will take care of it.            {                war_timer_ptr_t my_timer_ptr = this;                mPool.PushTask(new WarTimerEventTask(my_event, my_timer_ptr));            }        }        catch(WarException& e)        {            log_error << "Caught unexcpected exception from DoTimer(). "                << e.Explain()                << war_endl;        }        #if WAR_CATCH_ALL            catch(...)        {            log_error << "Caught unknown exception from DoTimer().", NULL);            continue;        }#endif    }    SetState(STATE_QUITTING);        // Avoid dead-lock, other thearde may poll on this pointer, waiting for it to    // be NULL, while keeping a reference to us...    if (spThis == this)        spThis = NULL;}void WarTimer::OnCompleted(war_timer_event_ptr_t& my_event){    WarTimerEvent& revent = *my_event;    WarTime next_time;        switch(revent.GetType())    {    case WarTimerEvent::TIMER_ONCE:        return;    case WarTimerEvent::TIMER_LOOP_RELATIVE:        next_time.mTime += revent.GetDelay();        break;    case WarTimerEvent::TIMER_LOOP_ABSOLUTE:        next_time.mTime = revent.mTime.mTime + revent.GetDelay();        break;    }        assert(revent.GetDelay() > 0);    revent.SetTime(next_time);    if (revent.IsFast())    {        AUTO_LOCK        mEvents.insert(my_event);    }    else        AddEvent(my_event);}/////////////////////////////// PRIVATE    ///////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -