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