]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/timer.cpp
Better way even than suggested.
[user/henk/code/inspircd.git] / src / timer.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #include "inspircd.h"
15 #include "timer.h"
16
17 void TimerManager::TickTimers(time_t TIME)
18 {
19         timerlist::iterator found = Timers.find(TIME);
20
21         if (found != Timers.end())
22         {
23                 timergroup* x = found->second;
24                 /*
25                  * There are pending timers to trigger
26                  */
27                 for (timergroup::iterator y = x->begin(); y != x->end(); y++)
28                 {
29                         InspTimer* n = *y;
30                         n->Tick(TIME);
31                         if (n->GetRepeat())
32                         {
33                                 AddTimer(n, n->GetSecs());
34                         }
35                         else
36                         {
37                                 DELETE(n);
38                         }
39                 }
40
41                 Timers.erase(found);
42                 DELETE(x);
43         }
44 }
45
46 void TimerManager::DelTimer(InspTimer* T)
47 {
48         timerlist::iterator found = Timers.find(T->GetTimer());
49
50         if (found != Timers.end())
51         {
52                 timergroup* x = found->second;
53                 for (timergroup::iterator y = x->begin(); y != x->end(); y++)
54                 {
55                         InspTimer* n = *y;
56                         if (n == T)
57                         {
58                                 DELETE(n);
59                                 x->erase(y);
60                                 if (!x->size())
61                                         Timers.erase(found);
62                                 return;
63                         }
64                 }
65         }
66 }
67
68 /*
69  * Because some muppets may do odd things, and their ircd may lock up due
70  * to crappy 3rd party modules, or they may change their system time a bit,
71  * this accounts for shifts of up to 120 secs by looking behind for missed
72  * timers and executing them. This is only executed once every 5 secs.
73  * If you move your clock BACK, and your timers move further ahead as a result,
74  * then tough titty you'll just have to wait.
75  */
76 void TimerManager::TickMissedTimers(time_t TIME)
77 {
78         for (time_t n = TIME-1; n > TIME-120; n--)
79         {
80                 timerlist::iterator found = Timers.find(n);
81                 if (found != Timers.end())
82                 {
83                         timergroup* x = found->second;
84                         for (timergroup::iterator y = x->begin(); y != x->end(); y++)
85                         {
86                                 InspTimer* z = *y;
87                                 z->Tick(TIME);
88                                 if (z->GetRepeat())
89                                 {
90                                         AddTimer(z, z->GetSecs());
91                                 }
92                                 else
93                                 {
94                                         DELETE(z);
95                                 }
96                         }
97
98                         Timers.erase(found);
99                         DELETE(x);
100                 }
101         }
102 }
103
104 void TimerManager::AddTimer(InspTimer* T, long secs_from_now)
105 {
106         timergroup* x = NULL;
107
108         int time_to_trigger = 0;
109         if (!secs_from_now)
110                 time_to_trigger = T->GetTimer();
111         else
112                 time_to_trigger = secs_from_now + time(NULL);
113
114         timerlist::iterator found = Timers.find(time_to_trigger);
115
116         if (found != Timers.end())
117         {
118                 x = found->second;
119         }
120         else
121         {
122                 x = new timergroup;
123                 Timers[time_to_trigger] = x;
124         }
125
126         x->push_back(T);
127 }
128