1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16 // Copyright (c) 1996-2020, Live Networks, Inc. All rights reserved
17// Delay queue
18// C++ header
19
20#ifndef _DELAY_QUEUE_HH
21#define _DELAY_QUEUE_HH
22
23#ifndef _NET_COMMON_H
24#include "NetCommon.h"
25#endif
26
27#ifdef TIME_BASE
28typedef TIME_BASE time_base_seconds;
29#else
30typedef long time_base_seconds;
31#endif
32
33///// A "Timeval" can be either an absolute time, or a time interval /////
34
35class Timeval {
36public:
37 time_base_seconds seconds() const {
38 return fTv.tv_sec;
39 }
40 time_base_seconds seconds() {
41 return fTv.tv_sec;
42 }
43 time_base_seconds useconds() const {
44 return fTv.tv_usec;
45 }
46 time_base_seconds useconds() {
47 return fTv.tv_usec;
48 }
49
50 int operator>=(Timeval const& arg2) const;
51 int operator<=(Timeval const& arg2) const {
52 return arg2 >= *this;
53 }
54 int operator<(Timeval const& arg2) const {
55 return !(*this >= arg2);
56 }
57 int operator>(Timeval const& arg2) const {
58 return arg2 < *this;
59 }
60 int operator==(Timeval const& arg2) const {
61 return *this >= arg2 && arg2 >= *this;
62 }
63 int operator!=(Timeval const& arg2) const {
64 return !(*this == arg2);
65 }
66
67 void operator+=(class DelayInterval const& arg2);
68 void operator-=(class DelayInterval const& arg2);
69 // returns ZERO iff arg2 >= arg1
70
71protected:
72 Timeval(time_base_seconds seconds, time_base_seconds useconds) {
73 fTv.tv_sec = seconds; fTv.tv_usec = useconds;
74 }
75
76private:
77 time_base_seconds& secs() {
78 return (time_base_seconds&)fTv.tv_sec;
79 }
80 time_base_seconds& usecs() {
81 return (time_base_seconds&)fTv.tv_usec;
82 }
83
84 struct timeval fTv;
85};
86
87#ifndef max
88inline Timeval max(Timeval const& arg1, Timeval const& arg2) {
89 return arg1 >= arg2 ? arg1 : arg2;
90}
91#endif
92#ifndef min
93inline Timeval min(Timeval const& arg1, Timeval const& arg2) {
94 return arg1 <= arg2 ? arg1 : arg2;
95}
96#endif
97
98class DelayInterval operator-(Timeval const& arg1, Timeval const& arg2);
99// returns ZERO iff arg2 >= arg1
100
101
102///// DelayInterval /////
103
104class DelayInterval: public Timeval {
105public:
106 DelayInterval(time_base_seconds seconds, time_base_seconds useconds)
107 : Timeval(seconds, useconds) {}
108};
109
110DelayInterval operator*(short arg1, DelayInterval const& arg2);
111
112extern DelayInterval const DELAY_ZERO;
113extern DelayInterval const DELAY_SECOND;
114extern DelayInterval const DELAY_MINUTE;
115extern DelayInterval const DELAY_HOUR;
116extern DelayInterval const DELAY_DAY;
117
118///// _EventTime /////
119
120class _EventTime: public Timeval {
121public:
122 _EventTime(unsigned secondsSinceEpoch = 0,
123 unsigned usecondsSinceEpoch = 0)
124 // We use the Unix standard epoch: January 1, 1970
125 : Timeval(secondsSinceEpoch, usecondsSinceEpoch) {}
126};
127
128_EventTime TimeNow();
129
130extern _EventTime const THE_END_OF_TIME;
131
132
133///// DelayQueueEntry /////
134
135class DelayQueueEntry {
136public:
137 virtual ~DelayQueueEntry();
138
139 intptr_t token() {
140 return fToken;
141 }
142
143protected: // abstract base class
144 DelayQueueEntry(DelayInterval delay);
145
146 virtual void handleTimeout();
147
148private:
149 friend class DelayQueue;
150 DelayQueueEntry* fNext;
151 DelayQueueEntry* fPrev;
152 DelayInterval fDeltaTimeRemaining;
153
154 intptr_t fToken;
155 static intptr_t tokenCounter;
156};
157
158///// DelayQueue /////
159
160class DelayQueue: public DelayQueueEntry {
161public:
162 DelayQueue();
163 virtual ~DelayQueue();
164
165 void addEntry(DelayQueueEntry* newEntry); // returns a token for the entry
166 void updateEntry(DelayQueueEntry* entry, DelayInterval newDelay);
167 void updateEntry(intptr_t tokenToFind, DelayInterval newDelay);
168 void removeEntry(DelayQueueEntry* entry); // but doesn't delete it
169 DelayQueueEntry* removeEntry(intptr_t tokenToFind); // but doesn't delete it
170
171 DelayInterval const& timeToNextAlarm();
172 void handleAlarm();
173
174private:
175 DelayQueueEntry* head() { return fNext; }
176 DelayQueueEntry* findEntryByToken(intptr_t token);
177 void synchronize(); // bring the 'time remaining' fields up-to-date
178
179 _EventTime fLastSyncTime;
180};
181
182#endif
183