| /********** |
| This library is free software; you can redistribute it and/or modify it under |
| the terms of the GNU Lesser General Public License as published by the |
| Free Software Foundation; either version 2.1 of the License, or (at your |
| option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.) |
| |
| This library is distributed in the hope that it will be useful, but WITHOUT |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for |
| more details. |
| |
| You should have received a copy of the GNU Lesser General Public License |
| along with this library; if not, write to the Free Software Foundation, Inc., |
| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| **********/ |
| // Copyright (c) 1996-2015, Live Networks, Inc. All rights reserved |
| // Delay queue |
| // C++ header |
| |
| #ifndef _DELAY_QUEUE_HH |
| #define _DELAY_QUEUE_HH |
| |
| #ifndef _NET_COMMON_H |
| #include "NetCommon.h" |
| #endif |
| |
| #ifdef TIME_BASE |
| typedef TIME_BASE time_base_seconds; |
| #else |
| typedef long time_base_seconds; |
| #endif |
| |
| ///// A "Timeval" can be either an absolute time, or a time interval ///// |
| |
| class Timeval { |
| public: |
| time_base_seconds seconds() const { |
| return fTv.tv_sec; |
| } |
| time_base_seconds seconds() { |
| return fTv.tv_sec; |
| } |
| time_base_seconds useconds() const { |
| return fTv.tv_usec; |
| } |
| time_base_seconds useconds() { |
| return fTv.tv_usec; |
| } |
| |
| int operator>=(Timeval const& arg2) const; |
| int operator<=(Timeval const& arg2) const { |
| return arg2 >= *this; |
| } |
| int operator<(Timeval const& arg2) const { |
| return !(*this >= arg2); |
| } |
| int operator>(Timeval const& arg2) const { |
| return arg2 < *this; |
| } |
| int operator==(Timeval const& arg2) const { |
| return *this >= arg2 && arg2 >= *this; |
| } |
| int operator!=(Timeval const& arg2) const { |
| return !(*this == arg2); |
| } |
| |
| void operator+=(class DelayInterval const& arg2); |
| void operator-=(class DelayInterval const& arg2); |
| // returns ZERO iff arg2 >= arg1 |
| |
| protected: |
| Timeval(time_base_seconds seconds, time_base_seconds useconds) { |
| fTv.tv_sec = seconds; fTv.tv_usec = useconds; |
| } |
| |
| private: |
| time_base_seconds& secs() { |
| return (time_base_seconds&)fTv.tv_sec; |
| } |
| time_base_seconds& usecs() { |
| return (time_base_seconds&)fTv.tv_usec; |
| } |
| |
| struct timeval fTv; |
| }; |
| |
| #ifndef max |
| inline Timeval max(Timeval const& arg1, Timeval const& arg2) { |
| return arg1 >= arg2 ? arg1 : arg2; |
| } |
| #endif |
| #ifndef min |
| inline Timeval min(Timeval const& arg1, Timeval const& arg2) { |
| return arg1 <= arg2 ? arg1 : arg2; |
| } |
| #endif |
| |
| class DelayInterval operator-(Timeval const& arg1, Timeval const& arg2); |
| // returns ZERO iff arg2 >= arg1 |
| |
| |
| ///// DelayInterval ///// |
| |
| class DelayInterval: public Timeval { |
| public: |
| DelayInterval(time_base_seconds seconds, time_base_seconds useconds) |
| : Timeval(seconds, useconds) {} |
| }; |
| |
| DelayInterval operator*(short arg1, DelayInterval const& arg2); |
| |
| extern DelayInterval const DELAY_ZERO; |
| extern DelayInterval const DELAY_SECOND; |
| extern DelayInterval const DELAY_MINUTE; |
| extern DelayInterval const DELAY_HOUR; |
| extern DelayInterval const DELAY_DAY; |
| |
| ///// _EventTime ///// |
| |
| class _EventTime: public Timeval { |
| public: |
| _EventTime(unsigned secondsSinceEpoch = 0, |
| unsigned usecondsSinceEpoch = 0) |
| // We use the Unix standard epoch: January 1, 1970 |
| : Timeval(secondsSinceEpoch, usecondsSinceEpoch) {} |
| }; |
| |
| _EventTime TimeNow(); |
| |
| extern _EventTime const THE_END_OF_TIME; |
| |
| |
| ///// DelayQueueEntry ///// |
| |
| class DelayQueueEntry { |
| public: |
| virtual ~DelayQueueEntry(); |
| |
| intptr_t token() { |
| return fToken; |
| } |
| |
| protected: // abstract base class |
| DelayQueueEntry(DelayInterval delay); |
| |
| virtual void handleTimeout(); |
| |
| private: |
| friend class DelayQueue; |
| DelayQueueEntry* fNext; |
| DelayQueueEntry* fPrev; |
| DelayInterval fDeltaTimeRemaining; |
| |
| intptr_t fToken; |
| static intptr_t tokenCounter; |
| }; |
| |
| ///// DelayQueue ///// |
| |
| class DelayQueue: public DelayQueueEntry { |
| public: |
| DelayQueue(); |
| virtual ~DelayQueue(); |
| |
| void addEntry(DelayQueueEntry* newEntry); // returns a token for the entry |
| void updateEntry(DelayQueueEntry* entry, DelayInterval newDelay); |
| void updateEntry(intptr_t tokenToFind, DelayInterval newDelay); |
| void removeEntry(DelayQueueEntry* entry); // but doesn't delete it |
| DelayQueueEntry* removeEntry(intptr_t tokenToFind); // but doesn't delete it |
| |
| DelayInterval const& timeToNextAlarm(); |
| void handleAlarm(); |
| |
| private: |
| DelayQueueEntry* head() { return fNext; } |
| DelayQueueEntry* findEntryByToken(intptr_t token); |
| void synchronize(); // bring the 'time remaining' fields up-to-date |
| |
| _EventTime fLastSyncTime; |
| }; |
| |
| #endif |