IBR-DTNSuite
0.8
|
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 Timer::time_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 join(); 00038 } 00039 00040 void Timer::__cancellation() 00041 { 00042 MutexLock l(_state); 00043 _state.setState(TIMER_CANCELLED); 00044 _state.abort(); 00045 } 00046 00047 void Timer::set(size_t timeout) 00048 { 00049 MutexLock l(_state); 00050 _timeout = timeout * 1000; 00051 _state.setState(TIMER_RESET); 00052 } 00053 00054 void Timer::reset() 00055 { 00056 MutexLock l(_state); 00057 _state.setState(TIMER_RESET); 00058 } 00059 00060 void Timer::pause() 00061 { 00062 MutexLock l(_state); 00063 _state.setState(TIMER_STOPPED); 00064 } 00065 00066 size_t Timer::getTimeout() const 00067 { 00068 return _timeout / 1000; 00069 } 00070 00071 void Timer::run() 00072 { 00073 MutexLock l(_state); 00074 _state.setState(TIMER_RUNNING); 00075 00076 while (_state.ifState(TIMER_RUNNING) || _state.ifState(TIMER_STOPPED)) 00077 { 00078 try { 00079 if(_state.ifState(TIMER_RUNNING)) 00080 { 00081 if(_timeout > 0) 00082 { 00083 _state.wait(_timeout); 00084 } 00085 else 00086 { 00087 throw ibrcommon::Conditional::ConditionalAbortException(ibrcommon::Conditional::ConditionalAbortException::COND_ABORT); 00088 } 00089 } 00090 else 00091 { 00092 _state.wait(); 00093 } 00094 00095 // got signal, check for reset request 00096 if (_state.ifState(TIMER_RESET)) 00097 { 00098 _state.setState(TIMER_RUNNING); 00099 } 00100 else if(!_state.ifState(TIMER_STOPPED)) 00101 { 00102 // stop the timer 00103 _state.setState(TIMER_CANCELLED); 00104 } 00105 } 00106 catch (const ibrcommon::Conditional::ConditionalAbortException &ex) 00107 { 00108 switch (ex.reason) 00109 { 00110 case ibrcommon::Conditional::ConditionalAbortException::COND_TIMEOUT: 00111 { 00112 try 00113 { 00114 // timeout exceeded, call callback method 00115 _timeout = _callback.timeout(this) * 1000; 00116 _state.setState(TIMER_RUNNING); 00117 } 00118 catch(const StopTimerException &ex) 00119 { 00120 // stop the timer 00121 _state.setState(TIMER_STOPPED); 00122 } 00123 break; 00124 } 00125 00126 case ibrcommon::Conditional::ConditionalAbortException::COND_ABORT: 00127 case ibrcommon::Conditional::ConditionalAbortException::COND_ERROR: 00128 { 00129 _state.setState(TIMER_CANCELLED); 00130 return; 00131 } 00132 } 00133 } 00134 00135 yield(); 00136 } 00137 } 00138 }