|
reSIProcate/rutil
9694
|
00001 #ifndef RUTIL_GENERICTIMERQUEUE_HXX 00002 #define RUTIL_GENERICTIMERQUEUE_HXX 00003 00004 #include "rutil/Timer.hxx" 00005 #include <set> 00006 #include <vector> 00007 00008 namespace resip { 00009 00010 // !dcm! -- hoist? 00011 template<class T> 00012 class GenericTimerQueue 00013 { 00014 public: 00015 00016 // !dcm! -- can def. hoist 00017 template<class E> 00018 class TimerEntry 00019 { 00020 public: 00021 TimerEntry(unsigned long tms, E* event) : 00022 mWhen(tms + Timer::getTimeMs()), 00023 mEvent(event) 00024 { 00025 } 00026 00027 E* getEvent() const 00028 { 00029 return mEvent; 00030 } 00031 00032 bool operator<(const TimerEntry<E>& rhs) const 00033 { 00034 return mWhen < rhs.mWhen; 00035 } 00036 UInt64 mWhen; 00037 E* mEvent; 00038 }; 00039 00041 virtual ~GenericTimerQueue() 00042 { 00043 for (typename std::multiset<TimerEntry<T> >::iterator i = mTimers.begin(); i != mTimers.end(); ++i) 00044 { 00045 delete i->mEvent; 00046 } 00047 } 00048 00049 virtual void process() 00050 { 00051 if (!mTimers.empty() && msTillNextTimer() == 0) 00052 { 00053 TimerEntry<T> now(0, 0); 00054 00055 // hacky solution, needs work, insertion from processTimer 00056 // caused bizarre infinite loop issues in previous revision; 00057 // this code is in desperate need of help 00058 typedef typename std::multiset<TimerEntry<T> > TimerSet; 00059 typedef std::vector<typename TimerSet::iterator> ItVector; 00060 ItVector iterators; 00061 00062 typename TimerSet::iterator end = mTimers.upper_bound(now); 00063 typename TimerSet::iterator begin = mTimers.begin(); 00064 00065 for (typename TimerSet::iterator i = begin; i != end; ++i) 00066 { 00067 iterators.push_back(i); 00068 } 00069 00070 for (typename ItVector::iterator i = iterators.begin(); i != iterators.end(); ++i) 00071 { 00072 assert((*i)->getEvent()); 00073 processTimer((*i)->getEvent()); 00074 } 00075 00077 for (typename ItVector::iterator i = iterators.begin(); i != iterators.end(); ++i) 00078 { 00079 mTimers.erase(*i); 00080 } 00081 } 00082 } 00083 00084 virtual void processTimer(T*)=0; 00085 00086 void add(T* event, unsigned long msOffset) 00087 { 00088 TimerEntry<T> t(msOffset, event); 00089 mTimers.insert(t); 00090 } 00091 00092 int size() const 00093 { 00094 return mTimers.size(); 00095 } 00096 00097 bool empty() const 00098 { 00099 return mTimers.empty(); 00100 } 00101 00102 unsigned int msTillNextTimer() 00103 { 00104 if (!mTimers.empty()) 00105 { 00106 UInt64 next = mTimers.begin()->mWhen; 00107 UInt64 now = Timer::getTimeMs(); 00108 if (now > next) 00109 { 00110 return 0; 00111 } 00112 else 00113 { 00114 UInt64 ret64 = next - now; 00115 if ( ret64 > UInt64(INT_MAX) ) 00116 { 00117 return INT_MAX; 00118 } 00119 else 00120 { 00121 int ret = int(ret64); 00122 return ret; 00123 } 00124 } 00125 } 00126 else 00127 { 00128 return INT_MAX; 00129 } 00130 } 00131 00132 00133 protected: 00134 // friend std::ostream& operator<<(std::ostream&, const GenericTimerQueue&); 00135 std::multiset<TimerEntry<T> > mTimers; 00136 }; 00137 00138 } 00139 00140 #endif // RUTIL_GENERICTIMERQUEUE_HXX
1.7.5.1