]> jfr.im git - solanum.git/blame - librb/src/event.c
OpenSSL: Initialise if LibreSSL
[solanum.git] / librb / src / event.c
CommitLineData
db137867
AC
1/*
2 * ircd-ratbox: A slightly useful ircd.
3 * event.c: Event functions.
4 *
5 * Copyright (C) 1998-2000 Regents of the University of California
6 * Copyright (C) 2001-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * Code borrowed from the squid web cache by Adrian Chadd.
10 * Original header:
11 *
12 * DEBUG: section 41 Event Processing
13 * AUTHOR: Henrik Nordstrom
14 *
15 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
16 * ----------------------------------------------------------
17 *
18 * Squid is the result of efforts by numerous individuals from the
19 * Internet community. Development is led by Duane Wessels of the
20 * National Laboratory for Applied Network Research and funded by the
21 * National Science Foundation. Squid is Copyrighted (C) 1998 by
22 * the Regents of the University of California. Please see the
23 * COPYRIGHT file for full details. Squid incorporates software
24 * developed and/or copyrighted by other sources. Please see the
25 * CREDITS file for full details.
26 *
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
31 *
32 * This program is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
36 *
37 * You should have received a copy of the GNU General Public License
38 * along with this program; if not, write to the Free Software
39 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
40 * USA
41 *
db137867
AC
42 */
43
fe037171
EM
44#include <librb_config.h>
45#include <rb_lib.h>
db137867
AC
46#include <commio-int.h>
47#include <event-int.h>
48
3202e249
VY
49#define EV_NAME_LEN 33
50static char last_event_ran[EV_NAME_LEN];
db137867
AC
51static rb_dlink_list event_list;
52
53static time_t event_time_min = -1;
db137867
AC
54
55/*
55abcbb2 56 * struct ev_entry *
db137867
AC
57 * rb_event_find(EVH *func, void *arg)
58 *
59 * Input: Event function and the argument passed to it
60 * Output: Index to the slow in the event_table
61 * Side Effects: None
62 */
63static struct ev_entry *
64rb_event_find(EVH * func, void *arg)
65{
66 rb_dlink_node *ptr;
67 struct ev_entry *ev;
68 RB_DLINK_FOREACH(ptr, event_list.head)
69 {
70 ev = ptr->data;
71 if((ev->func == func) && (ev->arg == arg))
72 return ev;
73 }
74
75 return NULL;
76}
77
8ace0906
SA
78static
79struct ev_entry *
80rb_event_add_common(const char *name, EVH * func, void *arg, time_t when, time_t frequency)
81{
82 struct ev_entry *ev;
83 ev = rb_malloc(sizeof(struct ev_entry));
84 ev->func = func;
85 ev->name = rb_strndup(name, EV_NAME_LEN);
86 ev->arg = arg;
87 ev->when = rb_current_time() + when;
88 ev->next = when;
89 ev->frequency = frequency;
90
91 if((ev->when < event_time_min) || (event_time_min == -1))
92 event_time_min = ev->when;
93
94 rb_dlinkAdd(ev, &ev->node, &event_list);
95 rb_io_sched_event(ev, when);
96 return ev;
97}
98
db137867 99/*
55abcbb2 100 * struct ev_entry *
db137867
AC
101 * rb_event_add(const char *name, EVH *func, void *arg, time_t when)
102 *
103 * Input: Name of event, function to call, arguments to pass, and frequency
104 * of the event.
105 * Output: None
106 * Side Effects: Adds the event to the event list.
107 */
108struct ev_entry *
109rb_event_add(const char *name, EVH * func, void *arg, time_t when)
110{
8db50c03
KB
111 if (rb_unlikely(when <= 0)) {
112 rb_lib_log("rb_event_add: tried to schedule %s event with a delay of "
113 "%d seconds", name, (int) when);
114 when = 1;
115 }
db137867 116
8ace0906 117 return rb_event_add_common(name, func, arg, when, when);
db137867 118}
3202e249 119
db137867
AC
120struct ev_entry *
121rb_event_addonce(const char *name, EVH * func, void *arg, time_t when)
122{
8db50c03
KB
123 if (rb_unlikely(when <= 0)) {
124 rb_lib_log("rb_event_addonce: tried to schedule %s event to run in "
125 "%d seconds", name, (int) when);
126 when = 1;
127 }
db137867 128
8ace0906 129 return rb_event_add_common(name, func, arg, when, 0);
db137867
AC
130}
131
132/*
133 * void rb_event_delete(struct ev_entry *ev)
134 *
135 * Input: pointer to ev_entry for the event
136 * Output: None
137 * Side Effects: Removes the event from the event list
138 */
139void
140rb_event_delete(struct ev_entry *ev)
141{
142 if(ev == NULL)
143 return;
144
145 rb_dlinkDelete(&ev->node, &event_list);
146 rb_io_unsched_event(ev);
3202e249 147 rb_free(ev->name);
db137867
AC
148 rb_free(ev);
149}
150
151/*
152 * void rb_event_find_delete(EVH *func, void *arg)
153 *
154 * Input: pointer to func and data
155 * Output: None
156 * Side Effects: Removes the event from the event list
157 */
158void
3202e249 159rb_event_find_delete(EVH * func, void *arg)
db137867
AC
160{
161 rb_event_delete(rb_event_find(func, arg));
162}
163
8ace0906
SA
164static time_t
165rb_event_frequency(time_t frequency)
166{
167 if(frequency < 0)
168 {
a1125230 169 const time_t two_third = (2 * labs(frequency)) / 3;
8ace0906
SA
170 frequency = two_third + ((rand() % 1000) * two_third) / 1000;
171 }
172 return frequency;
173}
174
55abcbb2 175/*
db137867
AC
176 * struct ev_entry *
177 * rb_event_addish(const char *name, EVH *func, void *arg, time_t delta_isa)
178 *
179 * Input: Name of event, function to call, arguments to pass, and frequency
180 * of the event.
181 * Output: None
182 * Side Effects: Adds the event to the event list within +- 1/3 of the
183 * specified frequency.
184 */
185struct ev_entry *
186rb_event_addish(const char *name, EVH * func, void *arg, time_t delta_ish)
187{
a1125230 188 delta_ish = labs(delta_ish);
db137867 189 if(delta_ish >= 3.0)
8ace0906
SA
190 delta_ish = -delta_ish;
191 return rb_event_add_common(name, func, arg,
192 rb_event_frequency(delta_ish), delta_ish);
db137867
AC
193}
194
195
196void
0e651b14 197rb_run_one_event(struct ev_entry *ev)
db137867 198{
3202e249 199 rb_strlcpy(last_event_ran, ev->name, sizeof(last_event_ran));
db137867
AC
200 ev->func(ev->arg);
201 if(!ev->frequency)
202 {
1d393245 203 rb_event_delete(ev);
db137867
AC
204 return;
205 }
8ace0906 206 ev->when = rb_current_time() + rb_event_frequency(ev->frequency);
db137867
AC
207 if((ev->when < event_time_min) || (event_time_min == -1))
208 event_time_min = ev->when;
209}
210
211/*
212 * void rb_event_run(void)
213 *
214 * Input: None
215 * Output: None
216 * Side Effects: Runs pending events in the event list
217 */
218void
219rb_event_run(void)
220{
221 rb_dlink_node *ptr, *next;
222 struct ev_entry *ev;
3202e249 223
db137867
AC
224 if(rb_io_supports_event())
225 return;
226
227 event_time_min = -1;
228 RB_DLINK_FOREACH_SAFE(ptr, next, event_list.head)
229 {
230 ev = ptr->data;
231 if(ev->when <= rb_current_time())
232 {
3202e249 233 rb_strlcpy(last_event_ran, ev->name, sizeof(last_event_ran));
db137867
AC
234 ev->func(ev->arg);
235
236 /* event is scheduled more than once */
3202e249 237 if(ev->frequency)
db137867 238 {
8ace0906 239 ev->when = rb_current_time() + rb_event_frequency(ev->frequency);
db137867
AC
240 if((ev->when < event_time_min) || (event_time_min == -1))
241 event_time_min = ev->when;
242 }
243 else
244 {
245 rb_dlinkDelete(&ev->node, &event_list);
246 rb_free(ev);
247 }
3202e249
VY
248 }
249 else
250 {
db137867
AC
251 if((ev->when < event_time_min) || (event_time_min == -1))
252 event_time_min = ev->when;
253 }
254 }
255}
256
257void
258rb_event_io_register_all(void)
259{
260 rb_dlink_node *ptr;
261 struct ev_entry *ev;
030272f3 262
db137867
AC
263 if(!rb_io_supports_event())
264 return;
3202e249 265
db137867 266 RB_DLINK_FOREACH(ptr, event_list.head)
3202e249 267 {
db137867 268 ev = ptr->data;
030272f3 269 rb_io_sched_event(ev, ev->next);
db137867
AC
270 }
271}
3202e249 272
db137867
AC
273/*
274 * void rb_event_init(void)
275 *
276 * Input: None
277 * Output: None
55abcbb2 278 * Side Effects: Initializes the event system.
db137867
AC
279 */
280void
281rb_event_init(void)
282{
3202e249 283 rb_strlcpy(last_event_ran, "NONE", sizeof(last_event_ran));
db137867
AC
284}
285
286void
287rb_dump_events(void (*func) (char *, void *), void *ptr)
288{
289 int len;
290 char buf[512];
291 rb_dlink_node *dptr;
292 struct ev_entry *ev;
293 len = sizeof(buf);
3202e249 294
5203cba5 295 snprintf(buf, len, "Last event to run: %s", last_event_ran);
3202e249
VY
296 func(buf, ptr);
297
db137867
AC
298 rb_strlcpy(buf, "Operation Next Execution", len);
299 func(buf, ptr);
300
301 RB_DLINK_FOREACH(dptr, event_list.head)
302 {
303 ev = dptr->data;
8ace0906
SA
304 snprintf(buf, len, "%-28s %-4ld seconds (frequency=%d)", ev->name,
305 ev->when - (long)rb_current_time(), (int)ev->frequency);
db137867
AC
306 func(buf, ptr);
307 }
308}
309
55abcbb2 310/*
db137867
AC
311 * void rb_set_back_events(time_t by)
312 * Input: Time to set back events by.
313 * Output: None.
314 * Side-effects: Sets back all events by "by" seconds.
315 */
316void
317rb_set_back_events(time_t by)
318{
319 rb_dlink_node *ptr;
320 struct ev_entry *ev;
321 RB_DLINK_FOREACH(ptr, event_list.head)
322 {
323 ev = ptr->data;
324 if(ev->when > by)
325 ev->when -= by;
326 else
327 ev->when = 0;
328 }
329}
330
331void
332rb_event_update(struct ev_entry *ev, time_t freq)
333{
334 if(ev == NULL)
335 return;
336
337 ev->frequency = freq;
338
8ace0906 339 /* update when it's scheduled to run if it's higher
db137867
AC
340 * than the new frequency
341 */
8ace0906
SA
342 time_t next = rb_event_frequency(freq);
343 if((rb_current_time() + next) < ev->when)
344 ev->when = rb_current_time() + next;
db137867
AC
345 return;
346}
347
348time_t
349rb_event_next(void)
350{
351 return event_time_min;
352}