1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd: (C) 2002-2008 InspIRCd Development Team
* See: http://www.inspircd.org/wiki/index.php/Credits
*
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef INSPIRCD_TIMER_H
#define INSPIRCD_TIMER_H
class InspIRCd;
/** Timer class for one-second resolution timers
* InspTimer provides a facility which allows module
* developers to create one-shot timers. The timer
* can be made to trigger at any time up to a one-second
* resolution. To use InspTimer, inherit a class from
* InspTimer, then insert your inherited class into the
* queue using Server::AddTimer(). The Tick() method of
* your object (which you should override) will be called
* at the given time.
*/
class CoreExport InspTimer : public Extensible
{
private:
/** The triggering time
*/
time_t trigger;
/** Number of seconds between triggers
*/
long secs;
/** True if this is a repeating timer
*/
bool repeat;
public:
/** Default constructor, initializes the triggering time
* @param secs_from_now The number of seconds from now to trigger the timer
* @param now The time now
* @param repeating Repeat this timer every secs_from_now seconds if set to true
*/
InspTimer(long secs_from_now,time_t now, bool repeating = false)
{
trigger = now + secs_from_now;
secs = secs_from_now;
repeat = repeating;
}
/** Default destructor, does nothing.
*/
virtual ~InspTimer() { }
/** Retrieve the current triggering time
*/
virtual time_t GetTimer()
{
return trigger;
}
/** Called when the timer ticks.
* You should override this method with some useful code to
* handle the tick event.
*/
virtual void Tick(time_t TIME) = 0;
/** Returns true if this timer is set to repeat
*/
bool GetRepeat()
{
return repeat;
}
/** Returns the interval (number of seconds between ticks)
* of this timer object.
*/
long GetSecs()
{
return secs;
}
/** Cancels the repeat state of a repeating timer.
* If you call this method, then the next time your
* timer ticks, it will be removed immediately after.
* You should use this method call to remove a recurring
* timer if you wish to do so within the timer's Tick
* event, as calling TimerManager::DelTimer() from within
* the InspTimer::Tick() method is dangerous and may
* cause a segmentation fault. Calling CancelRepeat()
* is safe in this case.
*/
void CancelRepeat()
{
repeat = false;
}
};
/** This class manages sets of InspTimers, and triggers them at their defined times.
* This will ensure timers are not missed, as well as removing timers that have
* expired and allowing the addition of new ones.
*/
class CoreExport TimerManager : public Extensible
{
protected:
/** A group of timers all set to trigger at the same time
*/
typedef std::vector<InspTimer*> timergroup;
/** A map of timergroups, each group has a specific trigger time
*/
typedef std::map<time_t, timergroup*> timerlist;
/** Set when ticking timers, to prevent deletion while iterating
*/
bool CantDeleteHere;
/** Creating server instance
*/
InspIRCd* ServerInstance;
private:
/** The current timer set, a map of timergroups
*/
timerlist Timers;
public:
/** Constructor
*/
TimerManager(InspIRCd* Instance);
/** Tick all pending InspTimers
* @param TIME the current system time
*/
void TickTimers(time_t TIME);
/** Add an InspTimer
* @param T an InspTimer derived class to add
* @param secs_from_now You may set this to the number of seconds
* from the current time when the timer will tick, or you may just
* leave this unset and the values set by the InspTimers constructor
* will be used. This is used internally for re-triggering repeating
* timers.
*/
void AddTimer(InspTimer* T, long secs_from_now = 0);
/** Delete an InspTimer
* @param T an InspTimer derived class to delete
*/
void DelTimer(InspTimer* T);
/** Tick any timers that have been missed due to lag
* @param TIME the current system time
*/
void TickMissedTimers(time_t TIME);
};
#endif
|