New file |
| | |
| | | /********** |
| | | 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 3 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-2017, 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 |