|
IBR-DTNSuite 0.6
|
00001 /* 00002 * Timer.cpp 00003 * 00004 * Created on: 29.09.2009 00005 * Author: morgenro 00006 */ 00007 00008 #include "ibrcommon/config.h" 00009 #include "ibrcommon/thread/Timer.h" 00010 #include "ibrcommon/thread/MutexLock.h" 00011 00012 #include <iostream> 00013 #include <queue> 00014 #include <utility> 00015 #include <sstream> 00016 00017 namespace ibrcommon 00018 { 00019 size_t Timer::get_current_time() 00020 { 00021 time_t rawtime = time(NULL); 00022 tm * ptm; 00023 00024 ptm = gmtime ( &rawtime ); 00025 00026 return mktime(ptm); 00027 } 00028 00029 Timer::Timer(TimerCallback &callback, size_t timeout) 00030 : _state(TIMER_UNSET), _callback(callback), _timeout(timeout * 1000) 00031 { 00032 } 00033 00034 Timer::~Timer() 00035 { 00036 stop(); 00037 } 00038 00039 bool Timer::__cancellation() 00040 { 00041 { 00042 MutexLock l(_state); 00043 _state.setState(TIMER_STOPPED); 00044 _state.abort(); 00045 } 00046 join(); 00047 00048 return true; 00049 } 00050 00051 void Timer::set(size_t timeout) 00052 { 00053 MutexLock l(_state); 00054 _timeout = timeout * 1000; 00055 _state.setState(TIMER_RESET); 00056 } 00057 00058 void Timer::reset() 00059 { 00060 MutexLock l(_state); 00061 _state.setState(TIMER_RESET); 00062 } 00063 00064 void Timer::run() 00065 { 00066 MutexLock l(_state); 00067 _state.setState(TIMER_RUNNING); 00068 00069 while (_state.ifState(TIMER_RUNNING)) 00070 { 00071 try { 00072 _state.wait(_timeout); 00073 00074 // got signal, check for reset request 00075 if (_state.ifState(TIMER_RESET)) 00076 { 00077 _state.setState(TIMER_RUNNING); 00078 } 00079 else 00080 { 00081 // stop the timer 00082 _state.setState(TIMER_STOPPED); 00083 } 00084 } 00085 catch (const ibrcommon::Conditional::ConditionalAbortException &ex) 00086 { 00087 switch (ex.reason) 00088 { 00089 case ibrcommon::Conditional::ConditionalAbortException::COND_TIMEOUT: 00090 { 00091 // timeout exceeded, call callback method 00092 if (_callback.timeout(this)) 00093 { 00094 // reset the timer 00095 _state.setState(TIMER_RUNNING); 00096 } 00097 else 00098 { 00099 // stop the timer 00100 _state.setState(TIMER_STOPPED); 00101 } 00102 break; 00103 } 00104 00105 case ibrcommon::Conditional::ConditionalAbortException::COND_ABORT: 00106 { 00107 if (_state.ifState(TIMER_STOPPED)) return; 00108 break; 00109 } 00110 00111 case ibrcommon::Conditional::ConditionalAbortException::COND_ERROR: 00112 break; 00113 } 00114 } 00115 00116 yield(); 00117 } 00118 } 00119 00120 SimpleTimer::SimpleTimer(SimpleTimerCallback &callback, size_t identifier) 00121 : _callback(callback), _identifier(identifier) 00122 { 00123 } 00124 00125 SimpleTimer::~SimpleTimer() 00126 { 00127 stop(); 00128 join(); 00129 } 00130 00131 void SimpleTimer::set(size_t timeout) 00132 { 00133 ibrcommon::MutexLock l(_timercond); 00134 _timeout = timeout * 1000; 00135 } 00136 00137 bool SimpleTimer::__cancellation() 00138 { 00139 { 00140 ibrcommon::MutexLock l(_timercond); 00141 _timercond.abort(); 00142 } 00143 00144 return true; 00145 } 00146 00147 void SimpleTimer::remove() 00148 { 00149 stop(); 00150 } 00151 00152 void SimpleTimer::run() 00153 { 00154 ibrcommon::MutexLock l(_timercond); 00155 00156 // create 00157 struct timespec ts; 00158 ibrcommon::Conditional::gettimeout(_timeout, &ts); 00159 00160 while (true) 00161 { 00162 try { 00163 // wait for the timeout or abort signal 00164 _timercond.wait(&ts); 00165 } catch (const ibrcommon::Conditional::ConditionalAbortException &ex) { 00166 switch (ex.reason) 00167 { 00168 case ibrcommon::Conditional::ConditionalAbortException::COND_TIMEOUT: 00169 // on timeout call the callback method 00170 _timeout = _callback.timeout(_identifier) * 1000; 00171 00172 // set the new timeout value 00173 ibrcommon::Conditional::gettimeout(_timeout, &ts); 00174 break; 00175 00176 case ibrcommon::Conditional::ConditionalAbortException::COND_ERROR: 00177 case ibrcommon::Conditional::ConditionalAbortException::COND_ABORT: 00178 return; 00179 } 00180 } 00181 00182 yield(); 00183 } 00184 } 00185 }