Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Timer.cpp

Go to the documentation of this file.
00001 #include "headers.h"
00002 
00014 
00018 Timer::Timer() {
00019     m_destroyed = false;
00020     m_name = "<unnamed>";
00021     pthread_attr_t attr;
00022         pthread_attr_init(&attr);
00023         pthread_create(&m_timerThreadId, &attr, timerThread, this);
00024     pthread_attr_destroy(&attr);
00025 } // ctor
00026 
00027 
00031 Timer::~Timer() {
00032     m_eventListMutex.lock();
00033     list<TimerNode*>::iterator iter;
00034     for (iter = m_eventList.begin(); iter != m_eventList.end(); ++iter) {
00035         delete *iter;
00036     }
00037     m_eventList.clear();
00038     m_destroyed = true;
00039     addEvent(0, NULL, NULL, NULL);
00040     m_eventListMutex.unlock();
00041     void* statusp;
00042     pthread_join(m_timerThreadId, &statusp);
00043 } // dtor
00044 
00045 
00051 void
00052 Timer::setName(string name) {
00053     m_name = name;
00054 } // fn setName
00055 
00056 
00060 string
00061 Timer::getName() {
00062     return m_name;
00063 } // fn getName
00064 
00065 
00070 void* 
00071 Timer::timerThread(void* arg)
00072 {
00073     Timer* timer = (Timer*)arg;
00074     timer->timerThreadImpl();
00075     return NULL;
00076 }
00077 
00078 
00086 void 
00087 Timer::timerThreadImpl() {
00088         m_eventListMutex.lock();
00089     string timerName = getName();
00090         debug(DEBUG_TIMER, "%s: started", timerName.c_str());
00091     TimeValue wakeupTime;
00092     while (true) {
00093         if (m_eventList.empty()) {
00094             m_eventListSignal.wait(&m_eventListMutex);
00095         }
00096         else {
00097             wakeupTime = m_eventList.front()->getWakeup();
00098             m_eventListSignal.timedWait(&m_eventListMutex, &(wakeupTime.getTimespecStruct()));
00099         }
00100 
00101         //we have been killed
00102                 if (m_destroyed) {
00103                         debug(DEBUG_TIMER, "%s: killed", timerName.c_str()); 
00104                         m_eventListMutex.unlock();
00105                         return;
00106                 }
00107 
00108         if (!m_eventList.empty()) {
00109             // It is possible to wake up early.  In this case, just start waiting again.
00110             if (!m_eventList.front()->past()) {
00111                 debug(DEBUG_TIMER, "%s: Woke up early", timerName.c_str());
00112                 continue;
00113             }
00114             
00115             //start the function on a new thread if the event is still relevent
00116             if (m_eventList.front()->isValid()) {
00117                 debug(DEBUG_TIMER, "%s: Event is valid, performing action...", timerName.c_str());
00118                 doAction(m_eventList.front());
00119             } // if
00120             else {
00121                 debug(DEBUG_TIMER, "%s: Event canceled", timerName.c_str());
00122             }
00123             
00124             //remove the node
00125             TimerNode* t = m_eventList.front();
00126             delete t;
00127             m_eventList.pop_front();
00128         }
00129         } // while (true)
00130 } //fn timerThread
00131 
00132 
00142 void 
00143 Timer::addEvent(int millisec, void* (*func)(void*), void* arg, bool* set)
00144 {       
00145     Guard guard(&m_eventListMutex);
00146 
00147     TimeValue dispatchTime = TimeValue::getCurrentTime() + TimeValue(0, millisec * 1000);
00148 
00149         TimerNode* entry = new TimerNode(func, arg, dispatchTime, set);
00150         MEMCHECK(entry);
00151 
00152         if ((m_eventList.empty()) || (*entry < *m_eventList.front())) //adding to the front of the list
00153         {
00154         m_eventList.push_front(entry);
00155                 m_eventListSignal.signal(); //reset the timer, this is new first
00156         }
00157         else //adding elsewhere, no need to reset the timer
00158         {
00159         list<TimerNode*>::iterator iter;
00160         for (iter = m_eventList.begin(); iter != m_eventList.end(); ++iter) {
00161             if (*entry < **iter) {
00162                 break;
00163             }
00164         }
00165         m_eventList.insert(iter, entry);
00166         }
00167 } //fn addEvent
00168 
00169 
00173 void
00174 Timer::toStream(std::ostream& out) 
00175 {
00176     Guard guard(&m_eventListMutex);
00177 
00178     list<TimerNode*>::iterator iter;
00179     for (iter = m_eventList.begin(); iter != m_eventList.end(); ++iter) {
00180                 out << "Event: ";
00181         out << **iter;
00182         } 
00183     TimeValue tmp(TimeValue::getCurrentTime());
00184     out << "Current time: " << tmp << "\n";
00185 } //fn toStream
00186 
00187 

Generated at Thu Jul 11 13:31:52 2002 for Peekabooty by doxygen1.2.9 written by Dimitri van Heesch, © 1997-2001