X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Ftime%2Ftimer.cpp;fp=source%2Ftime%2Ftimer.cpp;h=641d55f03b03a71d4b2a3a41cf04a7824aa56898;hb=e1ea831a640fba534e7e42e399f04cdf681ef8d3;hp=0000000000000000000000000000000000000000;hpb=0bcb8d4d6f33cbdad7b921cac787740bfe8e212e;p=libs%2Fcore.git diff --git a/source/time/timer.cpp b/source/time/timer.cpp new file mode 100644 index 0000000..641d55f --- /dev/null +++ b/source/time/timer.cpp @@ -0,0 +1,119 @@ +/* +This file is part of libmspframework +Copyright © 2006 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ +#include +#include "timer.h" +#include "utils.h" + +using namespace std; + +namespace Msp { +namespace Time { + +Timer::Timer(const Time::TimeDelta &d): + interval(d), + timeout(now()+d) +{ + MutexLock l(set_mutex); + timers.insert(this); + thread.nudge(); +} + +Timer::~Timer() +{ + MutexLock l(set_mutex); + timers.erase(this); + thread.nudge(); +} + +Timer::ThreadProxy Timer::thread; +Mutex Timer::set_mutex; +set Timer::timers; + +Timer::Thread::Thread(): + done(false) +{ + launch(); +} + +/** +Notifies the thread that a change in the timers occurred. +*/ +void Timer::Thread::nudge() +{ + sem.signal(); +} + +/** +Tells the thread to finish and terminate gracefully. This function will return +after the thread has terminated. +*/ +void Timer::Thread::finish() +{ + if(!done) + { + done=true; + sem.signal(); + } + + join(); +} + +void Timer::Thread::main() +{ + while(!done) + { + set_mutex.lock(); + Timer *next=0; + TimeStamp next_ts; + for(set::iterator i=timers.begin(); i!=timers.end(); ++i) + { + const TimeStamp &ts=(*i)->get_timeout(); + if(tssignal_timeout.emit()) + next->timeout+=next->interval; + else + delete next; + } + } + else + pause(); + } +} + +/** +Creates the thread if it doesn't exist, otherwise nudges it. +*/ +void Timer::ThreadProxy::nudge() +{ + if(!thread) + thread=new Thread(); + else + thread->nudge(); +} + +Timer::ThreadProxy::~ThreadProxy() +{ + if(thread) + { + thread->finish(); + delete thread; + } +} + +} // namespace Time +} // namespace Msp