timers.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:6k
源码类别:

通讯编程

开发平台:

Visual C++

  1. //
  2. // timers.cc       : Timer Management Class
  3. // authors         : John Heidemann, Fabio Silva and Alefiya Hussain 
  4. //
  5. // Copyright (C) 2000-2002 by the University of Southern California
  6. // $Id: timers.cc,v 1.4 2005/09/13 04:53:50 tomh Exp $
  7. //
  8. // This program is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU General Public License,
  10. // version 2, as published by the Free Software Foundation.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. // GNU General Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public License along
  18. // with this program; if not, write to the Free Software Foundation, Inc.,
  19. // 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  20. //
  21. // Linking this file statically or dynamically with other modules is making
  22. // a combined work based on this file.  Thus, the terms and conditions of
  23. // the GNU General Public License cover the whole combination.
  24. //
  25. // In addition, as a special exception, the copyright holders of this file
  26. // give you permission to combine this file with free software programs or
  27. // libraries that are released under the GNU LGPL and with code included in
  28. // the standard release of ns-2 under the Apache 2.0 license or under
  29. // otherwise-compatible licenses with advertising requirements (or modified
  30. // versions of such code, with unchanged license).  You may copy and
  31. // distribute such a system following the terms of the GNU GPL for this
  32. // file and the licenses of the other code concerned, provided that you
  33. // include the source code of that other code when and as the GNU GPL
  34. // requires distribution of source code.
  35. //
  36. // Note that people who make modified versions of this file are not
  37. // obligated to grant this special exception for their modified versions;
  38. // it is their choice whether to do so.  The GNU General Public License
  39. // gives permission to release a modified version without this exception;
  40. // this exception also makes it possible to release a modified version
  41. // which carries forward this exception.
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include "timers.hh"
  45. // Creates the Timer Management class. Creates the eventqueue The
  46. // eventqueue is used by the Timer class only.  Use the nextTimer and
  47. // executeNextTimer functions to access the event queue
  48. TimerManager::TimerManager()
  49. {
  50.   struct timeval tv;
  51.   // Initialize basic stuff
  52.   next_handle_ = 1;
  53.   GetTime(&tv);
  54.   SetSeed(&tv);
  55.   // Initialize event queue
  56. #ifdef NS_DIFFUSION
  57.   eq_ = new DiffEventQueue(this);
  58. #else
  59.   eq_ = new EventQueue;
  60. #endif // NS_DIFFUSION
  61. #ifdef USE_THREADS
  62.   queue_mtx_ = new pthread_mutex_t;
  63.   pthread_mutex_init(queue_mtx_, NULL);
  64. #endif // USE_THREADS
  65. }
  66. // This function adds a timer to the event queue. The timeout provided
  67. // should be in milliseconds. cb specifies the function that will be
  68. // called.
  69. handle TimerManager::addTimer(int timeout, TimerCallback *cb)
  70. {
  71.   TimerEntry *entry;
  72. #ifdef USE_THREADS
  73.   pthread_mutex_lock(queue_mtx_);
  74. #endif // USE_THREADS
  75.   entry = new TimerEntry(next_handle_, timeout, cb);
  76.   eq_->eqAddAfter(next_handle_, entry, timeout);
  77.   next_handle_++;
  78. #ifdef USE_THREADS
  79.   pthread_mutex_unlock(queue_mtx_);
  80. #endif // USE_THREADS
  81.   return entry->hdl_;
  82. }
  83. // Applications can use this function to remove from the eventqueue a
  84. // previously scheduled timer (the handle should be the one returned
  85. // by the AddTimer function)
  86. bool TimerManager::removeTimer(handle hdl)
  87. {
  88. #ifdef NS_DIFFUSION
  89.   if (eq_->eqRemove(hdl) == false){
  90.     fprintf(stderr, "Error: Can't remove event from queue !n");
  91.     return false;
  92.   }
  93.   return true;
  94. #else
  95.   QueueEvent *e = NULL;
  96.   TimerEntry *entry;
  97. #ifdef USE_THREADS
  98.   pthread_mutex_lock(queue_mtx_);
  99. #endif // USE_THREADS
  100.   // Find the timer in the queue
  101.   e = eq_->eqFindEvent(hdl);
  102.   // If timer found, remove it from the queue
  103.   if (e){
  104.     entry = (TimerEntry *) e->payload_;
  105.     if (eq_->eqRemove(hdl) == false){
  106.       fprintf(stderr, "Error: Can't remove event from queue !n");
  107.       exit(-1);
  108.     }
  109.     // Call the application provided delete function
  110.     delete entry;
  111.     delete e;
  112.   }
  113.   else{
  114. #ifdef USE_THREADS
  115.     pthread_mutex_unlock(queue_mtx_);
  116. #endif // USE_THREADS
  117.     return false;
  118.   }
  119. #ifdef USE_THREADS
  120.   pthread_mutex_unlock(queue_mtx_);
  121. #endif // USE_THREADS
  122.   return true;
  123. #endif // NS_DIFFUSION
  124. }
  125. // Returns the expiration value for the first timer on the queue
  126. void TimerManager::nextTimerTime(struct timeval *tv)
  127. {
  128. #ifdef USE_THREADS
  129.   pthread_mutex_lock(queue_mtx_);
  130. #endif // USE_THREADS
  131.   eq_->eqNextTimer(tv);
  132. #ifdef USE_THREADS
  133.   pthread_mutex_unlock(queue_mtx_);
  134. #endif // USE_THREADS
  135. }
  136. // Executes the first timer callback in the queue 
  137. #ifdef NS_DIFFUSION
  138. void TimerManager::diffTimeout(DiffEvent *e)
  139. {
  140.   TimerEntry *entry = (TimerEntry *) e->payload();
  141.   // run it
  142.   int new_timeout = entry->cb_->expire();
  143.   if (new_timeout >= 0){
  144.     if (new_timeout > 0){
  145.       // Change the timer's timeout
  146.       entry->timeout_ = new_timeout;
  147.     }
  148.     eq_->eqAddAfter(entry->hdl_, (TimerEntry *) entry, entry->timeout_);
  149.   }
  150.   else{
  151.     delete entry;
  152.   }
  153.   delete e;
  154. }
  155. #else
  156. void TimerManager::executeNextTimer()
  157. {
  158. #ifdef USE_THREADS
  159.   pthread_mutex_lock(queue_mtx_);
  160. #endif // USE_THREADS
  161.   QueueEvent *e = eq_->eqPop();
  162.   TimerEntry *entry = (TimerEntry *) e->payload_;
  163. #ifdef USE_THREADS
  164.   pthread_mutex_unlock(queue_mtx_);
  165. #endif // USE_THREADS
  166.   // run it
  167.   int new_timeout = entry->cb_->expire();
  168.   if (new_timeout >= 0){
  169.     if (new_timeout > 0){
  170.       // Change the timer's timeout
  171.       entry->timeout_ = new_timeout;
  172.     }
  173. #ifdef USE_THREADS
  174.     pthread_mutex_lock(queue_mtx_);
  175. #endif // USE_THREADS
  176.     eq_->eqAddAfter(entry->hdl_, (TimerEntry *) entry, entry->timeout_);
  177. #ifdef USE_THREADS
  178.     pthread_mutex_unlock(queue_mtx_);
  179. #endif // USE_THREADS
  180.   }
  181.   else{
  182.     delete entry;
  183.   }
  184.   delete e;
  185. }
  186. void TimerManager::executeAllExpiredTimers()
  187. {
  188.   struct timeval tv;
  189.   // Get next timer's timeout
  190.   nextTimerTime(&tv);
  191.   // Remove all expired timers from the top of the queue, calling
  192.   // expire() for each one of them
  193.   while (tv.tv_sec == 0 && tv.tv_usec == 0){
  194.     // Timer at the head of the queue has expired
  195.     executeNextTimer();
  196.     nextTimerTime(&tv);
  197.   }
  198. }
  199. #endif // NS_DIFFUSION