reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
GenericTimerQueue.hxx
Go to the documentation of this file.
1#ifndef RUTIL_GENERICTIMERQUEUE_HXX
2#define RUTIL_GENERICTIMERQUEUE_HXX
3
4#include "rutil/Timer.hxx"
5#include <set>
6#include <vector>
7
8namespace resip {
9
10// !dcm! -- hoist?
11template<class T>
13{
14 public:
15
16 // !dcm! -- can def. hoist
17 template<class E>
19 {
20 public:
21 TimerEntry(unsigned long tms, E* event) :
22 mWhen(tms + Timer::getTimeMs()),
23 mEvent(event)
24 {
25 }
26
27 E* getEvent() const
28 {
29 return mEvent;
30 }
31
32 bool operator<(const TimerEntry<E>& rhs) const
33 {
34 return mWhen < rhs.mWhen;
35 }
38 };
39
42 {
43 for (typename std::multiset<TimerEntry<T> >::iterator i = mTimers.begin(); i != mTimers.end(); ++i)
44 {
45 delete i->mEvent;
46 }
47 }
48
49 virtual void process()
50 {
51 if (!mTimers.empty() && msTillNextTimer() == 0)
52 {
53 TimerEntry<T> now(0, 0);
54
55 // hacky solution, needs work, insertion from processTimer
56 // caused bizarre infinite loop issues in previous revision;
57 // this code is in desperate need of help
58 typedef typename std::multiset<TimerEntry<T> > TimerSet;
59 typedef std::vector<typename TimerSet::iterator> ItVector;
60 ItVector iterators;
61
62 typename TimerSet::iterator end = mTimers.upper_bound(now);
63 typename TimerSet::iterator begin = mTimers.begin();
64
65 for (typename TimerSet::iterator i = begin; i != end; ++i)
66 {
67 iterators.push_back(i);
68 }
69
70 for (typename ItVector::iterator i = iterators.begin(); i != iterators.end(); ++i)
71 {
72 resip_assert((*i)->getEvent());
73 processTimer((*i)->getEvent());
74 }
75
77 for (typename ItVector::iterator i = iterators.begin(); i != iterators.end(); ++i)
78 {
79 mTimers.erase(*i);
80 }
81 }
82 }
83
84 virtual void processTimer(T*)=0;
85
86 void add(T* event, unsigned long msOffset)
87 {
88 TimerEntry<T> t(msOffset, event);
89 mTimers.insert(t);
90 }
91
92 int size() const
93 {
94 return mTimers.size();
95 }
96
97 bool empty() const
98 {
99 return mTimers.empty();
100 }
101
102 unsigned int msTillNextTimer()
103 {
104 if (!mTimers.empty())
105 {
106 uint64_t next = mTimers.begin()->mWhen;
108 if (now > next)
109 {
110 return 0;
111 }
112 else
113 {
114 uint64_t ret64 = next - now;
115 if ( ret64 > uint64_t(INT_MAX) )
116 {
117 return INT_MAX;
118 }
119 else
120 {
121 int ret = int(ret64);
122 return ret;
123 }
124 }
125 }
126 else
127 {
128 return INT_MAX;
129 }
130 }
131
132
133 protected:
134// friend std::ostream& operator<<(std::ostream&, const GenericTimerQueue&);
135 std::multiset<TimerEntry<T> > mTimers;
136};
137
138}
139
140#endif // RUTIL_GENERICTIMERQUEUE_HXX
#define resip_assert(x)
This file needs to work for both C and C++ code.
TimerEntry(unsigned long tms, E *event)
bool operator<(const TimerEntry< E > &rhs) const
virtual ~GenericTimerQueue()
deletes the message associated with the timer as well.
std::multiset< TimerEntry< T > > mTimers
void add(T *event, unsigned long msOffset)
virtual void processTimer(T *)=0
This class is used to get the current system time.
Definition Timer.hxx:31
static uint64_t getTimeMs()
Returns the current clock time in milliseconds.
Definition Timer.hxx:72
dcm! – add UnusedChecking(_enum) below;
unsigned long long uint64_t
Definition Stun.hxx:39