00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025
00026 #include "timers.hh"
00027
00028
00029
00030
00031
00032 TimerManager::TimerManager()
00033 {
00034 struct timeval tv;
00035
00036
00037 next_handle_ = 1;
00038 GetTime(&tv);
00039 SetSeed(&tv);
00040
00041
00042 #ifdef NS_DIFFUSION
00043 eq_ = new DiffEventQueue(this);
00044 #else
00045 eq_ = new EventQueue;
00046 #endif // NS_DIFFUSION
00047
00048 #ifdef USE_THREADS
00049 queue_mtx_ = new pthread_mutex_t;
00050 pthread_mutex_init(queue_mtx_, NULL);
00051 #endif // USE_THREADS
00052 }
00053
00054
00055
00056
00057
00058 handle TimerManager::addTimer(int timeout, TimerCallback *cb)
00059 {
00060 TimerEntry *entry;
00061
00062 #ifdef USE_THREADS
00063 pthread_mutex_lock(queue_mtx_);
00064 #endif // USE_THREADS
00065 entry = new TimerEntry(next_handle_, timeout, cb);
00066 eq_->eqAddAfter(next_handle_, entry, timeout);
00067 next_handle_++;
00068
00069 #ifdef USE_THREADS
00070 pthread_mutex_unlock(queue_mtx_);
00071 #endif // USE_THREADS
00072 return entry->hdl_;
00073 }
00074
00075
00076
00077
00078
00079 bool TimerManager::removeTimer(handle hdl)
00080 {
00081 #ifdef NS_DIFFUSION
00082 if (eq_->eqRemove(hdl) == false){
00083 fprintf(stderr, "Error: Can't remove event from queue !\n");
00084 return false;
00085 }
00086 return true;
00087 #else
00088 QueueEvent *e = NULL;
00089 TimerEntry *entry;
00090
00091 #ifdef USE_THREADS
00092 pthread_mutex_lock(queue_mtx_);
00093 #endif // USE_THREADS
00094
00095
00096 e = eq_->eqFindEvent(hdl);
00097
00098
00099 if (e){
00100 entry = (TimerEntry *) e->payload_;
00101 if (eq_->eqRemove(hdl) == false){
00102 fprintf(stderr, "Error: Can't remove event from queue !\n");
00103 exit(-1);
00104 }
00105
00106
00107
00108 delete entry;
00109 delete e;
00110 }
00111 else{
00112 #ifdef USE_THREADS
00113 pthread_mutex_unlock(queue_mtx_);
00114 #endif // USE_THREADS
00115 return false;
00116 }
00117
00118 #ifdef USE_THREADS
00119 pthread_mutex_unlock(queue_mtx_);
00120 #endif // USE_THREADS
00121 return true;
00122 #endif // NS_DIFFUSION
00123 }
00124
00125
00126 void TimerManager::nextTimerTime(struct timeval *tv)
00127 {
00128 #ifdef USE_THREADS
00129 pthread_mutex_lock(queue_mtx_);
00130 #endif // USE_THREADS
00131 eq_->eqNextTimer(tv);
00132 #ifdef USE_THREADS
00133 pthread_mutex_unlock(queue_mtx_);
00134 #endif // USE_THREADS
00135 }
00136
00137
00138 #ifdef NS_DIFFUSION
00139 void TimerManager::diffTimeout(DiffEvent *e)
00140 {
00141 TimerEntry *entry = (TimerEntry *) e->payload();
00142
00143
00144 int new_timeout = entry->cb_->expire();
00145
00146 if (new_timeout >= 0){
00147 if (new_timeout > 0){
00148
00149 entry->timeout_ = new_timeout;
00150 }
00151 eq_->eqAddAfter(entry->hdl_, (TimerEntry *) entry, entry->timeout_);
00152 }
00153 else{
00154 delete entry;
00155 }
00156 delete e;
00157 }
00158 #else
00159 void TimerManager::executeNextTimer()
00160 {
00161 #ifdef USE_THREADS
00162 pthread_mutex_lock(queue_mtx_);
00163 #endif // USE_THREADS
00164 QueueEvent *e = eq_->eqPop();
00165 TimerEntry *entry = (TimerEntry *) e->payload_;
00166
00167 #ifdef USE_THREADS
00168 pthread_mutex_unlock(queue_mtx_);
00169 #endif // USE_THREADS
00170
00171 int new_timeout = entry->cb_->expire();
00172
00173 if (new_timeout >= 0){
00174 if (new_timeout > 0){
00175
00176 entry->timeout_ = new_timeout;
00177 }
00178 #ifdef USE_THREADS
00179 pthread_mutex_lock(queue_mtx_);
00180 #endif // USE_THREADS
00181 eq_->eqAddAfter(entry->hdl_, (TimerEntry *) entry, entry->timeout_);
00182 #ifdef USE_THREADS
00183 pthread_mutex_unlock(queue_mtx_);
00184 #endif // USE_THREADS
00185 }
00186 else{
00187 delete entry;
00188 }
00189 delete e;
00190 }
00191
00192 void TimerManager::executeAllExpiredTimers()
00193 {
00194 struct timeval tv;
00195
00196
00197 nextTimerTime(&tv);
00198
00199
00200
00201 while (tv.tv_sec == 0 && tv.tv_usec == 0){
00202
00203 executeNextTimer();
00204 nextTimerTime(&tv);
00205 }
00206 }
00207 #endif // NS_DIFFUSION