00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "mmstools/mmstimer.h"
00034 #include <cerrno>
00035 #include <cstring>
00036
00037 extern "C" {
00038 #include <sys/time.h>
00039 #include <time.h>
00040 }
00041
00042 MMSTimer::MMSTimer(bool singleShot) :
00043 MMSThread("MMSTimer"),
00044 singleShot(singleShot),
00045 action(START),
00046 firsttime(true),
00047 secs(0),
00048 nSecs(0),
00049 ft_secs(0),
00050 ft_nSecs(0) {
00051 MMSThread::setStacksize(131072-4096);
00052
00053 pthread_mutex_init(&this->mutex, NULL);
00054 pthread_cond_init(&this->cond, NULL);
00055 }
00056
00057 MMSTimer::~MMSTimer() {
00058 if(isRunning()) {
00059 pthread_mutex_lock(&mutex);
00060 this->action = QUIT;
00061 pthread_cond_signal(&cond);
00062 pthread_mutex_unlock(&mutex);
00063 join();
00064 }
00065
00066 pthread_cond_destroy(&this->cond);
00067 pthread_mutex_destroy(&this->mutex);
00068 }
00069
00070 bool MMSTimer::start(unsigned int milliSeconds, unsigned int firsttime_ms) {
00071
00072
00073 this->nSecs = (milliSeconds % 1000) * 1000000;
00074 this->secs = milliSeconds / 1000;
00075 this->ft_nSecs = (firsttime_ms % 1000) * 1000000;
00076 this->ft_secs = firsttime_ms / 1000;
00077
00078 this->firsttime = true;
00079
00080 if (!isRunning()) {
00081
00082 return MMSThread::start();
00083 }
00084 else {
00085
00086 return restart();
00087 }
00088 }
00089
00090 bool MMSTimer::restart() {
00091 if(!isRunning()) {
00092 return false;
00093 }
00094
00095 pthread_mutex_lock(&mutex);
00096 this->action = RESTART;
00097 pthread_cond_signal(&cond);
00098 pthread_mutex_unlock(&mutex);
00099
00100 return true;
00101 }
00102
00103 bool MMSTimer::stop() {
00104 if(!isRunning()) {
00105 return false;
00106 }
00107
00108 pthread_mutex_lock(&mutex);
00109 this->action = STOP;
00110 pthread_cond_signal(&cond);
00111 pthread_mutex_unlock(&mutex);
00112
00113 return true;
00114 }
00115
00116 void MMSTimer::threadMain() {
00117
00118 if(this->secs == 0 && this->nSecs == 0) {
00119 return;
00120 }
00121
00122 struct timespec absTime;
00123
00124 pthread_mutex_lock(&this->mutex);
00125 while(this->action != QUIT) {
00126 clock_gettime(CLOCK_REALTIME, &absTime);
00127
00128 if (this->firsttime && (this->ft_secs != 0 || this->ft_nSecs != 0)) {
00129
00130 absTime.tv_sec += this->ft_secs;
00131 absTime.tv_nsec += this->ft_nSecs;
00132 }
00133 else {
00134 absTime.tv_sec += this->secs;
00135 absTime.tv_nsec += this->nSecs;
00136 }
00137 this->firsttime = false;
00138
00139 if(absTime.tv_nsec > 999999999) {
00140 absTime.tv_sec += 1;
00141 absTime.tv_nsec -= 999999999;
00142 }
00143
00144 if(pthread_cond_timedwait(&this->cond, &this->mutex, &absTime) == ETIMEDOUT) {
00145
00146 pthread_mutex_unlock(&this->mutex);
00147 this->timeOut.emit();
00148 pthread_mutex_lock(&this->mutex);
00149 if(this->singleShot)
00150 break;
00151 }
00152
00153 while(this->action == STOP) {
00154 pthread_cond_wait(&this->cond, &this->mutex);
00155 }
00156 }
00157 pthread_mutex_unlock(&this->mutex);
00158 }