IBR-DTNSuite  0.8
ibrcommon/ibrcommon/thread/Timer.cpp
Go to the documentation of this file.
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 }