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 }
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 }
00044
00045
00051 void
00052 Timer::setName(string name) {
00053 m_name = name;
00054 }
00055
00056
00060 string
00061 Timer::getName() {
00062 return m_name;
00063 }
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
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
00110 if (!m_eventList.front()->past()) {
00111 debug(DEBUG_TIMER, "%s: Woke up early", timerName.c_str());
00112 continue;
00113 }
00114
00115
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 }
00120 else {
00121 debug(DEBUG_TIMER, "%s: Event canceled", timerName.c_str());
00122 }
00123
00124
00125 TimerNode* t = m_eventList.front();
00126 delete t;
00127 m_eventList.pop_front();
00128 }
00129 }
00130 }
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()))
00153 {
00154 m_eventList.push_front(entry);
00155 m_eventListSignal.signal();
00156 }
00157 else
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 }
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 }
00186
00187