Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

timers.cc

Go to the documentation of this file.
00001 //
00002 // timers.cc       : Timer Management Class
00003 // authors         : John Heidemann, Fabio Silva and Alefiya Hussain 
00004 //
00005 // Copyright (C) 2000-2002 by the University of Southern California
00006 // $Id: timers.cc,v 1.2 2002/11/26 22:45:40 haldar Exp $
00007 //
00008 // This program is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU General Public License,
00010 // version 2, as published by the Free Software Foundation.
00011 //
00012 // This program is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License along
00018 // with this program; if not, write to the Free Software Foundation, Inc.,
00019 // 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00020 //
00021 
00022 
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 
00026 #include "timers.hh"
00027 
00028 // Creates the Timer Management class. Creates the eventqueue The
00029 // eventqueue is used by the Timer class only.  Use the nextTimer and
00030 // executeNextTimer functions to access the event queue
00031 
00032 TimerManager::TimerManager()
00033 {
00034   struct timeval tv;
00035 
00036   // Initialize basic stuff
00037   next_handle_ = 1;
00038   GetTime(&tv);
00039   SetSeed(&tv);
00040 
00041   // Initialize event queue
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 // This function adds a timer to the event queue. The timeout provided
00055 // should be in milliseconds. cb specifies the function that will be
00056 // called.
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 // Applications can use this function to remove from the eventqueue a
00076 // previously scheduled timer (the handle should be the one returned
00077 // by the AddTimer function)
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   // Find the timer in the queue
00096   e = eq_->eqFindEvent(hdl);
00097 
00098   // If timer found, remove it from the queue
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     // Call the application provided delete function
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 // Returns the expiration value for the first timer on the queue
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 // Executes the first timer callback in the queue 
00138 #ifdef NS_DIFFUSION
00139 void TimerManager::diffTimeout(DiffEvent *e)
00140 {
00141   TimerEntry *entry = (TimerEntry *) e->payload();
00142 
00143   // run it
00144   int new_timeout = entry->cb_->expire();
00145 
00146   if (new_timeout >= 0){
00147     if (new_timeout > 0){
00148       // Change the timer's timeout
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   // run it
00171   int new_timeout = entry->cb_->expire();
00172 
00173   if (new_timeout >= 0){
00174     if (new_timeout > 0){
00175       // Change the timer's timeout
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   // Get next timer's timeout
00197   nextTimerTime(&tv);
00198 
00199   // Remove all expired timers from the top of the queue, calling
00200   // expire() for each one of them
00201   while (tv.tv_sec == 0 && tv.tv_usec == 0){
00202     // Timer at the head of the queue has expired
00203     executeNextTimer();
00204     nextTimerTime(&tv);
00205   }
00206 }
00207 #endif // NS_DIFFUSION

Generated on Tue Apr 20 12:14:37 2004 for NS2.26SourcesOriginal by doxygen 1.3.3