-// -*- mode: C++; indent-tabs-mode: nil; -*-
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
#ifndef __timer_hh
#define __timer_hh
+/*! @file timer.hh
+ @brief Contains the Timer class, used for timed callbacks.
+*/
+
extern "C" {
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else // !TIME_WITH_SYS_TIME
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else // !HAVE_SYS_TIME_H
-# include <time.h>
-# endif // HAVE_SYS_TIME_H
-#endif // TIME_WITH_SYS_TIME
+#include <ctime>
}
-namespace otk {
+#include <queue>
+#include <vector>
-class OBTimerQueueManager;
+namespace otk {
-//! The data passed to the OBTimeoutHandler function.
+//! The Timer class implements timed callbacks.
/*!
- Note: this is a very useful place to put an object instance, and set the
- event handler to a static function in the same class.
+ The Timer class can be used to have a callback fire after a given time
+ interval. A created Timer will fire repetitively until it is destroyed.
*/
-typedef void *OBTimeoutData;
-//! The type of function which can be set as the callback for an OBTimer firing
-typedef void (*OBTimeoutHandler)(OBTimeoutData);
+class Timer {
+public:
+ //! Data type of Timer callback
+ typedef void (*TimeoutHandler)(void *data);
-//! A Timer class which will fire a function when its time elapses
-class OBTimer {
private:
- //! The manager which to add ourself to and remove ourself after we are done
- OBTimerQueueManager *manager;
- //! The function to call when the time elapses
- OBTimeoutHandler handler;
- //! The data which gets passed along to the OBTimeoutHandler
- OBTimeoutData data;
- //! Determines if the timer is currently started
- bool timing;
- //! When this is true, the timer will reset itself to fire again every time
- bool recur;
-
- //! The time at which the timer started
- timeval _start;
- //! The time at which the timer is going to fire
- timeval _timeout;
-
- //! Disallows copying of OBTimer objects
- OBTimer(const OBTimer&);
- //! Disallows copying of OBTimer objects
- OBTimer& operator=(const OBTimer&);
-
-public:
- //! Constructs a new OBTimer object
+ //! Compares two timeval structs
+ struct TimerCompare {
+ //! Compares two timeval structs
+ inline bool operator()(const Timer *a, const Timer *b) const {
+ return ((&a->_timeout)->tv_sec == (&b->_timeout)->tv_sec) ?
+ ((&a->_timeout)->tv_usec > (&b->_timeout)->tv_usec) :
+ ((&a->_timeout)->tv_sec > (&b->_timeout)->tv_sec);
+ }
+ };
+ friend struct TimerCompare; // give access to _timeout for shitty compilers
+
+ typedef
+ std::priority_queue<Timer*, std::vector<Timer*>, TimerCompare> TimerQ;
+
+ //! Milliseconds between timer firings
+ long _delay;
+ //! Callback for timer expiry
+ TimeoutHandler _action;
+ //! Data sent to callback
+ void *_data;
+ //! We overload the delete operator to just set this to true
+ bool _del_me;
+ //! The time the last fire should've been at
+ struct timeval _last;
+ //! When this timer will next trigger
+ struct timeval _timeout;
+
+ //! Queue of pending timers
+ static TimerQ _q;
+ //! Time next timer will expire
+ static timeval _nearest_timeout;
+ //! Time at start of current processing loop
+ static timeval _now;
+
+ //! Really delete something (not just flag for later)
/*!
- @param m The OBTimerQueueManager with which to associate. The manager
- specified will be resposible for making this timer fire.
- @param h The function to call when the timer fires
- @param d The data to pass along to the function call when the timer fires
+ @param self Timer to be deleted.
*/
- OBTimer(OBTimerQueueManager *m, OBTimeoutHandler h, OBTimeoutData d);
- //! Destroys the OBTimer object
- virtual ~OBTimer();
-
- //! Fires the timer, calling its OBTimeoutHandler
- void fireTimeout();
-
- //! Returns if the OBTimer is started and timing
- inline bool isTiming() const { return timing; }
- //! Returns if the OBTimer is going to repeat
- inline bool isRecurring() const { return recur; }
+ static void realDelete(Timer *self);
- //! Gets the amount of time the OBTimer should last before firing
- inline const timeval &getTimeout() const { return _timeout; }
- //! Gets the time at which the OBTimer started
- inline const timeval &getStartTime() const { return _start; }
-
- //! Gets the amount of time left before the OBTimer fires
- timeval timeRemaining(const timeval &tm) const;
- //! Returns if the OBTimer is past its timeout time, and should fire
- bool shouldFire(const timeval &tm) const;
-
- //! Gets the time at which the OBTimer will fire
- timeval endpoint() const;
-
- //! Sets the OBTimer to repeat or not
+ //! Adds a millisecond delay to a timeval structure
/*!
- @param b If true, the timer is set to repeat; otherwise, it will fire only
- once
+ @param a Amount of time to increment.
+ @param msec Number of milliseconds to increment by.
*/
- inline void recurring(bool b) { recur = b; }
+ static void timevalAdd(timeval &a, long msec);
- //! Sets the amount of time for the OBTimer to last in milliseconds
- /*!
- @param t The number of milliseconds the timer should last
- */
- void setTimeout(long t);
- //! Sets the amount of time the OBTimer should last before firing
+public:
+ //! Constructs a new running timer and queues it
/*!
- @param t The amount of time the timer should last
+ @param delay Time in milliseconds between firings
+ @param cb The function to be called on fire.
+ @param data Data to be passed to the callback on fire.
*/
- void setTimeout(const timeval &t);
+ Timer(long delay, TimeoutHandler cb, void *data);
- //! Causes the timer to begin
+ //! Overloaded delete so we can leave deleted objects in queue for later reap
/*!
- The timer fires after the time in OBTimer::getTimeout has passed since this
- function was called.
- Calling this function while the timer is already started will cause it to
- restart its countdown.
+ @param self Pointer to current instance of Timer.
*/
- void start(); // manager acquires timer
- //! Causes the timer to stop
+ void operator delete(void *self);
+
+ //! Dispatches all elligible timers, then optionally waits for X events
/*!
- The timer will no longer fire once this function has been called.
- Calling this function more than once does not have any effect.
+ @param wait Whether to wait for X events after processing timers.
*/
- void stop(); // manager releases timer
+ static void dispatchTimers(bool wait = true);
- //! Determines if this OBTimer will fire before a second OBTimer object
+ //! Returns a relative timeval (to pass select) of the next timer
/*!
- @param other The second OBTimer with which to compare
- @return true if this OBTimer will fire before 'other'; otherwise, false
+ @param tm Changed to hold the time until next timer.
+ @return true if there are any timers queued, and the timeout is being
+ returned in 'tm'. false if there are no timers queued.
*/
- bool operator<(const OBTimer& other) const
- { return shouldFire(other.endpoint()); }
+ static bool nearestTimeout(struct timeval &tm);
+
+ //! Initializes internal data before use
+ static void initialize(void);
+
+ //! Deletes all waiting timers
+ static void destroy(void);
};
}
-#endif // __timer_hh
+#endif // __timer.hh