]>
Commit | Line | Data |
---|---|---|
212380e3 AC |
1 | Overview of the event subsystem |
2 | Adrian Chadd <adrian@creative.net.au> | |
3 | ||
212380e3 AC |
4 | |
5 | One of the things that immediately struck me whilst first looking at the | |
6 | code was that the ircd periodically scheduled things in io_loop() but | |
7 | it did them manually. This is very wasteful and very tedious. | |
8 | ||
9 | Therefore, an event system was added to hybrid. src/event.c contains an | |
10 | event system ported from the squid web cache. It is pretty self contained, | |
11 | and only a few things (debugging, time resolution) needed changing. | |
12 | ||
13 | An event is scheduled through eventAdd() or eventAddIsh() : | |
14 | ||
15 | eventAdd(const char *name, EVH * func, void *arg, time_t when, int weight) | |
16 | eventAddIsh(const char *name, EVH * func, void *arg, time_t delta_ish, | |
17 | int weight) | |
18 | ||
19 | after 'when' (or delta_ish) seconds has elapsed from the time the above | |
20 | functions are called, the 'func' is called with the given data 'arg'. The | |
21 | event is then deleted. | |
22 | ||
23 | To delete an event, use eventDelete() : | |
24 | ||
25 | eventDelete(EVH * func, void *arg) | |
26 | ||
27 | An event is identified by its callback function and data pair. | |
28 | ||
29 | Events are run through eventRun(). This is designed to be called *BEFORE* | |
30 | your IO handlers, to let events scheduled immediately (ie a time of 0) | |
31 | to initiate IO before the IO handlers are called. | |
32 | ||
33 | (Believe me, its useful.) | |
34 | ||
35 | ||
36 | ||
37 | Example: | |
38 | ||
39 | Say you have something which must be called every 15 seconds. | |
40 | ||
41 | * You would first define the callback in your module: | |
42 | ||
43 | static EVH foo_periodic_event; | |
44 | static int initialised = 0; | |
45 | ||
46 | * You would then add the event in your initialization function: | |
47 | ||
48 | void foo_init(void) | |
49 | { | |
50 | if (!initialised) { | |
51 | eventAdd("foo_periodic_event", foo_periodic_event, NULL, 0, 0); | |
52 | initialised = 1; | |
53 | } | |
54 | } | |
55 | ||
56 | This will force the event to be called the next time eventRun() is called, | |
57 | rather than waiting 15 seconds. | |
58 | ||
59 | * You then define your event callback: | |
60 | ||
61 | static void | |
62 | foo_periodic_event(void *data) | |
63 | { | |
64 | /* We'd do our work here */ | |
65 | ||
66 | /* Then we'd finish */ | |
67 | eventAdd("foo_periodic_event", foo_periodic_event, NULL, 15, 0); | |
68 | } | |
69 | ||
70 | ||
71 | Notes: | |
72 | ||
73 | * I really should change the timeout value to be in milliseconds. Squid used | |
74 | a double, but Dianora had something against floating point code in the main | |
75 | loop (which is understandable). If someone wants a fun task .. :-) | |
76 | ||
77 | * Note that the 'name' parameter to eventAdd() / eventAddIsh() is a const | |
78 | char *, and is *not copied* but *referenced*. Therefore, it is in your | |
79 | best interest to use string constants. | |
80 | ||
81 | * /stats E for an oper shows pending events. Thanks Diane! | |
82 |