| 1 |
Overview of the event subsystem |
| 2 |
Adrian Chadd <adrian@creative.net.au> |
| 3 |
|
| 4 |
$Id: event.txt,v 1.3 2003/10/13 02:15:20 metalrock Exp $ |
| 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! |