]>
Commit | Line | Data |
---|---|---|
189935b1 | 1 | The IRC server is built around an event loop. Until the u2.10.11 |
2 | release, this event loop has been rather ad-hoc; timed events are | |
3 | hard-coded in, signals are handled inside the signal handler, etc. | |
4 | All of this has changed with u2.10.11. A new subsystem, the events | |
5 | subsystem, has been introduced; the new subsystem contains a | |
6 | generalization of the concept of an event. An event is a signal, the | |
7 | expiration of a timer, or some form of activity on a network socket. | |
8 | This new subsystem has the potential to vastly simplify the code that | |
9 | is arguably the core of any network program, and makes it much simpler | |
10 | to support more exotic forms of network activity monitoring than the | |
11 | conventional select() and poll() calls. | |
12 | ||
13 | The primary concepts that the events subsystem works with are the | |
14 | "event," represented by a struct Event, and the "generator." There | |
15 | are three types of generators: sockets, represented by struct Socket; | |
16 | signals, represented by struct Signal; and timers, represented by | |
17 | struct Timer. Each of these generators will be described in turn. | |
18 | ||
19 | Signals | |
20 | ||
21 | The signal is perhaps the simplest generator in the entire events | |
22 | subsystem. Basically, instead of setting a signal handler, the | |
23 | function signal_add() is called, specifying a function to be called | |
24 | when a given signal is detected. Most importantly, that call-back | |
25 | function is called _outside_ the context of a signal handler, | |
26 | permitting the call-back to use more exotic functions that are | |
27 | anathema within a signal handler, such as MyMalloc(). Once a | |
28 | call-back for a signal has been established, it cannot be deleted; | |
29 | this design decision was driven by the fact that ircd never changes | |
30 | its signal handlers. | |
31 | ||
32 | Whenever a signal is received, an event of type ET_SIGNAL is | |
33 | generated, and that event is passed to the event call-back function | |
34 | specified in the signal_add() call. | |
35 | ||
36 | Timers | |
37 | ||
38 | Execution of the call-back functions for a timer occur when that timer | |
39 | _expires_; when a timer expires depends on the type of timer and the | |
40 | expiration time that was used for that timer. A TT_ABSOLUTE timer, | |
41 | for instance, expires at exactly the time given as the expiration | |
42 | time. This time is a standard UNIX time_t value, measuring seconds | |
43 | since the UNIX epoch. The TT_ABSOLUTE timer type is complemented by | |
44 | the TT_RELATIVE timer; the time passed as its expiration time is | |
45 | relative to the current time. If a TT_RELATIVE timer is given an | |
46 | expiration time of 5, for instance, it will expire 5 seconds after the | |
47 | present time. Internally, TT_RELATIVE timers are converted into | |
48 | TT_ABSOLUTE timers, with the expiration time adjusted by addition of | |
49 | the current time. | |
50 | ||
51 | Those two types of timers, TT_ABSOLUTE and TT_RELATIVE, are | |
52 | single-shot timers. Once they expire, they are removed from the timer | |
53 | list unless re-added by the event call-back or through some other | |
54 | mechanism. There is another type of timer, however, the TT_PERIODIC | |
55 | timer, that is not removed from the timer list. TT_PERIODIC timers | |
56 | are similar to TT_RELATIVE timers, in that one passes in the expire | |
57 | time as a relative number of seconds, but when they expire, they are | |
58 | re-added to the timer list with the same relative expire time. This | |
59 | means that a TT_PERIODIC timer with an expire time of 5 seconds that | |
60 | is set at 11:50:00 will have its call-back called at 11:50:05, | |
61 | 11:50:10, 11:50:15, and so on. | |
62 | ||
63 | Timers have to be run by the event engines explicitly by calling | |
64 | timer_run() on the generator list passed to the engine event loop. | |
65 | In addition, engines may determine the next (absolute) time that a | |
66 | timer needs to be run by calling the timer_next() macro; this may be | |
67 | used to set a timeout on the engine's network activity monitoring | |
68 | function. Engines are described in detail below. | |
69 | ||
70 | When a timer expires, an event of ET_EXPIRE is generated, and the | |
71 | call-back function is called. When a timer is destroyed, either as | |
72 | the result of an expiration or as a result of an explicit timer_del() | |
73 | call, an event of ET_DESTROY is generated, notifying the call-back | |
74 | that the struct Timer can be deallocated. | |
75 | ||
76 | Sockets | |
77 | ||
78 | Perhaps the most complicated event generator in all of the event | |
79 | system is the socket, as described by struct Socket. This single | |
80 | classification covers datagram sockets and stream sockets. To | |
81 | differentiate the different kinds of sockets, there is a socket state | |
82 | associated with each socket. The available states are SS_CONNECTING, | |
83 | which indicates that a particular socket is in the process of | |
84 | completing a non-blocking connect(); SS_LISTENING, which indicates | |
85 | that a particular socket is a listening socket; SS_CONNECTED, which is | |
86 | the state of every other stream socket; SS_DATAGRAM, which is an | |
87 | ordinary datagram socket, and SS_CONNECTDG, which describes a | |
88 | connected datagram socket. (The SS_NOTSOCK state is for the internal | |
89 | use of the events system and will not be described here.) | |
90 | ||
91 | In addition to the socket states, there's also an event mask for each | |
92 | socket; this set of flags is used to tell the events subsystem what | |
93 | events the application is interested in for the socket. For | |
94 | SS_CONNECTING and SS_LISTENING sockets, this events mask has no | |
95 | meaning, but on the other socket states, the event mask is used to | |
96 | determine if the application is interested in readable | |
97 | (SOCK_EVENT_READABLE) or writable (SOCK_EVENT_WRITABLE) indications. | |
98 | ||
99 | Most of the defined event types have to do with socket generators. | |
100 | When a socket turns up readable, for instance, an event of type | |
101 | ET_READ is generated. Similarly, ET_WRITE is generated when a socket | |
102 | can be written to. The ET_ACCEPT event is generated when a listening | |
103 | socket indicates that there is a connection to be accepted; ET_CONNECT | |
104 | is generated when a non-blocking connect is completed. Finally, if an | |
105 | end-of-file indication is detected, ET_EOF is generated, whereas if an | |
106 | error has occurred on the socket, ET_ERROR is generated. Of course, | |
107 | when a socket has been deleted by the socket_del() function, an event | |
108 | of ET_DESTROY is generated when it is safe for the memory used by the | |
109 | struct Socket to be reclaimed. | |
110 | ||
111 | Events | |
112 | ||
113 | An event, represented by a struct Event, describes in detail all of | |
114 | the particulars of an event. Each event has a type, and an optional | |
115 | integer piece of data may be passed with some events--in particular, | |
116 | ET_SIGNAL events pass the signal number, and ET_ERROR events pass the | |
117 | errno value. The struct Event also contains a pointer to the | |
118 | structure describing the generated event--although it should be noted | |
119 | that the only way to disambiguate which type of generator is contained | |
120 | within the struct Event is by which call-back function has been | |
121 | called. | |
122 | ||
123 | All generators have a void pointer which can be used to pass important | |
124 | information to the call-back, such as a pointer to a struct Client. | |
125 | Additionally, generators have a reference count, and a union of a void | |
126 | pointer and an integer that should only be utilized by the event | |
127 | engine. Finally, there is also a field for flags, although the only | |
128 | flag of concern to the application (or the engine) is the active flag, | |
129 | which may be tested using the test macros described below. | |
130 | ||
131 | Whatever the generator, the call-back function is a function returning | |
132 | nothing (void) and taking as its sole argument a pointer to struct | |
133 | Event. This call-back function may be implemented as a single switch | |
134 | statement that calls out to appropriate external functions as needed. | |
135 | ||
136 | Engines | |
137 | ||
138 | Engines implement the actual socket event loop, and may also have some | |
139 | means of receiving signal events. Each engine has a name, which | |
140 | should describe what its core function is; for instance, the engine | |
141 | based on the standard select() function is named, simply, "select()." | |
142 | Each engine must implement several call-backs which are used to | |
143 | initialize the engine, notify the engine of sockets the application is | |
144 | interested in, etc. All of this data is described by a single struct | |
145 | Engine, which should be the only non-static variable or function in | |
146 | the engine's source file. | |
147 | ||
148 | The engine's event loop, pointed to by the eng_loop field of the | |
149 | struct Engine, must consist of a single while loop predicated on the | |
150 | global variable _running_. Additionally, this loop's final statement | |
151 | must be a call to timer_run(), to execute all timers that have become | |
152 | due. Ideally, this construction should be pulled out of each engine's | |
153 | eng_loop and put in the event_loop() function of the events | |
154 | subsystem. | |
155 | ||
156 | Reference Counts | |
157 | ||
158 | As mentioned previously, all generators keep a reference count. | |
159 | Should timer_del() or socket_del() be called on a generator with a | |
160 | non-zero reference count, for whatever reason, the actual destruction | |
161 | of the generator will be delayed until the reference count again | |
162 | reaches zero. This is used by the event loop to keep sockets that it | |
163 | is currently referencing from being deallocated before it is done | |
164 | checking all pending events on them. To increment the reference count | |
165 | by one, call gen_ref_inc() on the generator; the corresponding macro | |
166 | gen_ref_dec() decrements the reference counts, and will automatically | |
167 | destroy the generator if the appropriate conditions are met. | |
168 | ||
169 | Debugging Functions | |
170 | ||
171 | It can be difficult to debug an engines if, say, a socket state can | |
172 | only be expressed as a meaningless number. Therefore, when DEBUGMODE | |
173 | is #define'd, five number-to-name functions are also defined to make | |
174 | the debugging data more meaningful. These functions must only be | |
175 | called when DEBUGMODE is #define'd. Calling them from within Debug() | |
176 | macro calls is safe; calling them from log_write() calls is not. | |
177 | ||
178 | <typedef> | |
179 | typedef void (*EventCallBack)(struct Event*); | |
180 | ||
181 | The _EventCallBack_ type is used to simplify declaration of event | |
182 | call-back functions. It is used in timer_add(), signal_add(), and | |
183 | socket_add(). The event call-back should process the event, taking | |
184 | whatever actions are necessary. The function should be declared as | |
185 | returning void. | |
186 | </typedef> | |
187 | ||
188 | <typedef> | |
189 | typedef int (*EngineInit)(int); | |
190 | ||
191 | The _EngineInit_ function takes an integer specifying the maximum | |
192 | number of sockets the event system is expecting to handle. This | |
193 | number may be used by the engine initialization function for memory | |
194 | allocation computations. If initialization succeeds, this function | |
195 | must return 1. If initialization fails, the function should clean up | |
196 | after itself and return 0. The events subsystem has the ability to | |
197 | fall back upon another engine, should an engine initialization fail. | |
198 | Needless to say, the engines based upon poll() and select() should | |
199 | never fail in this way. | |
200 | </typedef> | |
201 | ||
202 | <typedef> | |
203 | typedef void (*EngineSignal)(struct Signal*); | |
204 | ||
205 | If an engine has the capability to directly detect signals, it should | |
206 | set the eng_signal field of struct Engine non-zero. When the | |
207 | application indicates interest in a particular signal, the | |
208 | _EngineSignal_ function will be called with the filled-in struct | |
209 | Signal, in order to register interest in that signal with the engine. | |
210 | </typedef> | |
211 | ||
212 | <typedef> | |
213 | typedef int (*EngineAdd)(struct Socket*); | |
214 | ||
215 | All engines must define an _EngineAdd_ function, which is used to | |
216 | inform the engine of the application's interest in the socket. If the | |
217 | new socket cannot be accommodated by the engine for whatever reason, | |
218 | this function must return 0. Otherwise, the function must return 1, | |
219 | informing the events subsystem that the interest has been noted. | |
220 | </typedef> | |
221 | ||
222 | <typedef> | |
223 | typedef void (*EngineState)(struct Socket*, enum SocketState new_state); | |
224 | ||
225 | Sockets can change state. SS_CONNECTING sockets, for instance, can | |
226 | become SS_CONNECTED. Whenever a socket state changes, the engine is | |
227 | informed, since some states require different notification procedures | |
228 | than others. This is accomplished by calling the _EngineState_ | |
229 | function with the new state. The struct Socket passed to the engine | |
230 | will still have the old state, if the engine must reference that. | |
231 | </typedef> | |
232 | ||
233 | <typedef> | |
234 | typedef void (*EngineEvents)(struct Socket*, unsigned int new_events); | |
235 | ||
236 | Applications may only be interested in given events on a socket for a | |
237 | limited time. When the application's interest shifts, a new events | |
238 | mask is set for the socket. The engine is informed of this change by | |
239 | a call to its _EngineEvents_ function. | |
240 | </typedef> | |
241 | ||
242 | <typedef> | |
243 | typedef void (*EngineDelete)(struct Socket*); | |
244 | ||
245 | Eventually, an application will close all the sockets it has opened. | |
246 | When a socket is closed, and the corresponding struct Socket deleted | |
247 | with a call to socket_del(), the _EngineDelete_ function will be | |
248 | called to notify the engine of the change. | |
249 | </typedef> | |
250 | ||
251 | <typedef> | |
252 | typedef void (*EngineLoop)(struct Generators*); | |
253 | ||
254 | The workhorse of the entire events subsystem is the event loop, | |
255 | implemented by each engine as the _EngineLoop_ function. This | |
256 | function is called with a single argument that may be passed to | |
257 | timer_next() to calculate the next time a timer will expire. | |
258 | </typedef> | |
259 | ||
260 | <enum> | |
261 | enum SocketState { | |
262 | SS_CONNECTING, /* Connection in progress on socket */ | |
263 | SS_LISTENING, /* Socket is a listening socket */ | |
264 | SS_CONNECTED, /* Socket is a connected socket */ | |
265 | SS_DATAGRAM, /* Socket is a datagram socket */ | |
266 | SS_CONNECTDG, /* Socket is a connected datagram socket */ | |
267 | SS_NOTSOCK /* Socket isn't a socket at all */ | |
268 | }; | |
269 | ||
270 | This enumeration contains a list of all possible states a socket can | |
271 | be in. Applications should not use SS_NOTSOCK; engines should treat | |
272 | it as a special socket state for non-sockets. The only event that | |
273 | should be watched for on a struct Socket in the SS_NOTSOCK state is | |
274 | readability. This socket state is used to implement the fall-back | |
275 | signal event generation. | |
276 | </enum> | |
277 | ||
278 | <enum> | |
279 | enum TimerType { | |
280 | TT_ABSOLUTE, /* timer that runs at a specific time */ | |
281 | TT_RELATIVE, /* timer that runs so many seconds in the future */ | |
282 | TT_PERIODIC /* timer that runs periodically */ | |
283 | }; | |
284 | ||
285 | The three possible timer types are defined by the TimerType | |
286 | enumeration. More details can be found in the "Timers" sub-section. | |
287 | </enum> | |
288 | ||
289 | <enum> | |
290 | enum EventType { | |
291 | ET_READ, /* Readable event detected */ | |
292 | ET_WRITE, /* Writable event detected */ | |
293 | ET_ACCEPT, /* Connection can be accepted */ | |
294 | ET_CONNECT, /* Connection completed */ | |
295 | ET_EOF, /* End-of-file on connection */ | |
296 | ET_ERROR, /* Error condition detected */ | |
297 | ET_SIGNAL, /* A signal was received */ | |
298 | ET_EXPIRE, /* A timer expired */ | |
299 | ET_DESTROY /* The generator is being destroyed */ | |
300 | }; | |
301 | ||
302 | This enumeration contains all the types of events that can be | |
303 | generated by the events subsystem. The first 6 are generated by | |
304 | socket generators, the next by signal generators, and the next by | |
305 | timer generators. ET_DESTROY is generated by both socket and timer | |
306 | generators when the events subsystem is finished with the memory | |
307 | allocated by both. | |
308 | </enum> | |
309 | ||
310 | <struct> | |
311 | struct Socket; | |
312 | ||
313 | This structure describes everything the events subsystem knows about a | |
314 | given socket. All of its fields may be accessed through the s_* | |
315 | macros described below. | |
316 | </struct> | |
317 | ||
318 | <struct> | |
319 | struct Timer; | |
320 | ||
321 | The struct Timer structure describes everything the events subsystem | |
322 | knows about a given timer. Again, all of its fields may be accessed | |
323 | through the t_* macros described below. | |
324 | </struct> | |
325 | ||
326 | <struct> | |
327 | struct Signal; | |
328 | ||
329 | Signal generators are described by a struct Signal. All of the fields | |
330 | of a struct Signal may be accessed by the sig_* macros described | |
331 | below. | |
332 | </struct> | |
333 | ||
334 | <struct> | |
335 | struct Event; | |
336 | ||
337 | Each event is described by a struct Event. Its fields may be examined | |
338 | using the ev_* macros described below. | |
339 | </struct> | |
340 | ||
341 | <struct> | |
342 | struct Generators; | |
343 | ||
344 | Each engine is passed a list of all generators when the engine's | |
345 | _EngineLoop_ function is called. The only valid way to access this | |
346 | structure is via the timer_next() function described below. | |
347 | </struct> | |
348 | ||
349 | <struct> | |
350 | struct Engine { | |
351 | const char* eng_name; /* a name for the engine */ | |
352 | EngineInit eng_init; /* initialize engine */ | |
353 | EngineSignal eng_signal; /* express interest in a signal */ | |
354 | EngineAdd eng_add; /* express interest in a socket */ | |
355 | EngineState eng_state; /* mention a change in state to engine */ | |
356 | EngineEvents eng_events; /* express interest in socket events */ | |
357 | EngineDelete eng_closing; /* socket is being closed */ | |
358 | EngineLoop eng_loop; /* actual event loop */ | |
359 | }; | |
360 | ||
361 | Each engine is described by the struct Engine structure. Each engine | |
362 | must define all of the functions described above except for the | |
363 | _EngineSignal_ function, which is optional. | |
364 | </struct> | |
365 | ||
366 | <macro> | |
367 | #define SOCK_EVENT_READABLE 0x0001 /* interested in readable */ | |
368 | ||
369 | The SOCK_EVENT_READABLE flag indicates to the engine that the | |
370 | application is interested in readability on this particular socket. | |
371 | </macro> | |
372 | ||
373 | <macro> | |
374 | #define SOCK_EVENT_WRITABLE 0x0002 /* interested in writable */ | |
375 | ||
376 | The SOCK_EVENT_WRITABLE flag indicates to the engine that the | |
377 | application is interested in this socket being writable. | |
378 | </macro> | |
379 | ||
380 | <macro> | |
381 | #define SOCK_EVENT_MASK (SOCK_EVENT_READABLE | SOCK_EVENT_WRITABLE) | |
382 | ||
383 | SOCK_EVENT_MASK may be used to extract only the event interest flags | |
384 | from an event interest set. | |
385 | </macro> | |
386 | ||
387 | <macro> | |
388 | #define SOCK_ACTION_SET 0x0000 /* set interest set as follows */ | |
389 | ||
390 | When socket_events() is called with a set of event interest flags and | |
391 | SOCK_ACTION_SET, the socket's event interest flags are set to those | |
392 | passed into socket_events(). | |
393 | </macro> | |
394 | ||
395 | <macro> | |
396 | #define SOCK_ACTION_ADD 0x1000 /* add to interest set */ | |
397 | ||
398 | When SOCK_ACTION_ADD is used in a call to socket_events(), the event | |
399 | interest flags passed in are added to the existing event interest | |
400 | flags for the socket. | |
401 | </macro> | |
402 | ||
403 | <macro> | |
404 | #define SOCK_ACTION_DEL 0x2000 /* remove from interest set */ | |
405 | ||
406 | When SOCK_ACTION_DEL is used in a call to socket_events(), the event | |
407 | interest flags passed in are removed from the existing event interest | |
408 | flags for the socket. | |
409 | </macro> | |
410 | ||
411 | <macro> | |
412 | #define SOCK_ACTION_MASK 0x3000 /* mask out the actions */ | |
413 | ||
414 | SOCK_ACTION_MASK is used to isolate the socket action desired. | |
415 | </macro> | |
416 | ||
417 | <function> | |
418 | enum SocketState s_state(struct Socket* sock); | |
419 | ||
420 | This macro returns the state of the given socket. | |
421 | </function> | |
422 | ||
423 | <function> | |
424 | unsigned int s_events(struct Socket* sock); | |
425 | ||
426 | This macro returns the current event interest mask for a given | |
427 | socket. Note that if the socket is in the SS_CONNECTING or | |
428 | SS_LISTENING states, this mask has no meaning. | |
429 | </function> | |
430 | ||
431 | <function> | |
432 | int s_fd(struct Socket* sock); | |
433 | ||
434 | This macro simply returns the file descriptor for the given socket. | |
435 | </function> | |
436 | ||
437 | <function> | |
438 | void* s_data(struct Socket* sock); | |
439 | ||
440 | When a struct Socket is initialized, data that the call-back function | |
441 | may find useful, such as a pointer to a struct Connection, is stored | |
442 | in the struct Socket. This macro returns that pointer. | |
443 | </function> | |
444 | ||
445 | <function> | |
446 | int s_ed_int(struct Socket* sock); | |
447 | ||
448 | Engines may find it convenient to associate an integer with a struct | |
449 | Socket. This macro may be used to retrieve that integer or, when used | |
450 | as an lvalue, to assign a value to it. Engine data must be either an | |
451 | int or a void*; use of both is prohibited. | |
452 | </function> | |
453 | ||
454 | <function> | |
455 | void* s_ed_ptr(struct Socket* sock); | |
456 | ||
457 | Engines may find it convenient to associate a void* pointer with a | |
458 | struct Socket. This macro may be used to retrieve that pointer or, | |
459 | when used as an lvalue, to assign a value to it. Engine data must be | |
460 | either an int or a void*; use of both is prohibited. | |
461 | </function> | |
462 | ||
463 | <function> | |
464 | int s_active(struct Socket* sock); | |
465 | ||
466 | A socket's active flag is set when initialized by socket_add(), and is | |
467 | cleared immediately prior to generating an event of type ET_DESTROY. | |
468 | This may be used by the application to determine whether or not the | |
469 | socket is still in use by the events subsystem. If it is, s_active() | |
470 | returns a non-zero value; otherwise, its value is 0. | |
471 | </function> | |
472 | ||
473 | <function> | |
474 | int socket_add(struct Socket* sock, EventCallBack call, void* data, | |
475 | enum SocketState state, unsigned int events, int fd); | |
476 | ||
477 | This function is called to add a socket to the list of sockets to be | |
478 | monitored. The _sock_ parameter is a pointer to a struct Socket that | |
479 | is allocated by the application. The _call_ parameter is a pointer to | |
480 | a function to process any events on the socket. The _data_ parameter | |
481 | is for use of the socket call-back and may be zero. The _state_ | |
482 | parameter must be one of the valid socket states. The _events_ | |
483 | parameter must be a valid events interest mask--0, or the binary OR of | |
484 | SOCK_EVENT_READABLE or SOCK_EVENT_WRITABLE. Finally, the _fd_ | |
485 | parameter specifies the socket's file descriptor. This function | |
486 | returns 1 if successful or 0 otherwise. | |
487 | </function> | |
488 | ||
489 | <function> | |
490 | void socket_del(struct Socket* sock); | |
491 | ||
492 | When the application is no longer interested in a particular socket, | |
493 | it should call the socket_del() function. This function must be | |
494 | called no later than when the socket has been closed, to avoid | |
495 | attempting to call select() or similar functions on closed sockets. | |
496 | </function> | |
497 | ||
498 | <function> | |
499 | void socket_state(struct Socket* sock, enum SocketState state); | |
500 | ||
501 | Occasionally, a socket's state will change. This function is used to | |
502 | inform the events subsystem of that change. Only certain state | |
503 | transitions are valid--a socket in the SS_LISTENING or SS_CONNECTED | |
504 | states cannot change states, nor can an SS_CONNECTING socket change to | |
505 | some state other than SS_CONNECTED. Of course, SS_DATAGRAM sockets | |
506 | may change state only to SS_CONNECTDG, and SS_CONNECTDG sockets may | |
507 | only change states to SS_DATAGRAM. | |
508 | </function> | |
509 | ||
510 | <function> | |
511 | void socket_events(struct Socket* sock, unsigned int events); | |
512 | ||
513 | When the application changes the events it is interested in, it uses | |
514 | socket_events() to notify the events subsystem of that change. The | |
515 | _events_ parameter is the binary OR of one of SOCK_ACTION_SET, | |
516 | SOCK_ACTION_ADD, or SOCK_ACTION_DEL with an events mask. See the | |
517 | documentation for the SOCK_* macros for more information. | |
518 | </function> | |
519 | ||
520 | <function> | |
521 | const char* state_to_name(enum SocketState state); | |
522 | ||
523 | This function is defined only when DEBUGMODE is #define'd. It takes | |
524 | the given _state_ and returns a string giving that state's name. This | |
525 | function may safely be called from Debug() macros. | |
526 | </function> | |
527 | ||
528 | <function> | |
529 | const char* sock_flags(unsigned int flags); | |
530 | ||
531 | This function is defined only when DEBUGMODE is #define'd. It takes | |
532 | the given event interest flags and returns a string naming each of | |
533 | those flags. This function may safely be called from Debug() macros, | |
534 | but may only be called once, since it uses function static storage to | |
535 | store the flag strings. | |
536 | </function> | |
537 | ||
538 | <function> | |
539 | int sig_signal(struct Signal* sig); | |
540 | ||
541 | This macro returns the signal number for the given struct Signal. | |
542 | </function> | |
543 | ||
544 | <function> | |
545 | void* sig_data(struct Signal* sig); | |
546 | ||
547 | When a struct Signal is initialized, data that the call-back function | |
548 | may find useful is stored in the struct Signal. This macro returns | |
549 | that pointer. | |
550 | </function> | |
551 | ||
552 | <function> | |
553 | int sig_ed_int(struct Signal* sig); | |
554 | ||
555 | Engines may find it convenient to associate an integer with a struct | |
556 | Signal. This macro may be used to retrieve that integer or, when used | |
557 | as an lvalue, to assign a value to it. Engine data must be either an | |
558 | int or a void*; use of both is prohibited. | |
559 | </function> | |
560 | ||
561 | <function> | |
562 | void* sig_ed_ptr(struct Signal* sig); | |
563 | ||
564 | Engines may find it convenient to associate a void* pointer with a | |
565 | struct Signal. This macro may be used to retrieve that pointer or, | |
566 | when used as an lvalue, to assign a value to it. Engine data must be | |
567 | either an int or a void*; use of both is prohibited. | |
568 | </function> | |
569 | ||
570 | <function> | |
571 | int sig_active(struct Signal* sig); | |
572 | ||
573 | A signal's active flag is set when initialized by signal_add(). This | |
574 | may be used by the application to determine whether or not the signal | |
575 | has been initialized yet. If it is, sig_active() returns a non-zero | |
576 | value; otherwise, its value is 0. | |
577 | </function> | |
578 | ||
579 | <function> | |
580 | void signal_add(struct Signal* signal, EventCallBack call, void* data, | |
581 | int sig); | |
582 | ||
583 | This function is called to add a signal to the list of signals to be | |
584 | monitored. The _signal_ parameter is a pointer is a pointer to a | |
585 | struct Signal that is allocated by the application. The _call_ | |
586 | parameter is a pointer to a function to process any signal events. | |
587 | The _data_ parameter is for use of the signal call-back and may be | |
588 | zero. The _sig_ parameter is the integer value of the signal to be | |
589 | monitored. | |
590 | </function> | |
591 | ||
592 | <function> | |
593 | enum TimerType t_type(struct Timer* tim); | |
594 | ||
595 | This macro returns the type of the given timer. | |
596 | </function> | |
597 | ||
598 | <function> | |
599 | time_t t_value(struct Timer* tim); | |
600 | ||
601 | This macro returns the value that was used when the given timer was | |
602 | initialized by the events subsystem. It will contain an absolute time | |
603 | if the timer type is TT_ABSOLUTE, and a relative time otherwise. | |
604 | </function> | |
605 | ||
606 | <function> | |
607 | time_t t_expire(struct Timer* tim); | |
608 | ||
609 | This macro returns the absolute time at which the timer will next | |
610 | expire. | |
611 | </function> | |
612 | ||
613 | <function> | |
614 | void* t_data(struct Timer* tim); | |
615 | ||
616 | When a struct Timer is initialized, data that the call-back function | |
617 | may find useful is stored in the struct Socket. This macro returns | |
618 | that pointer. | |
619 | </function> | |
620 | ||
621 | <function> | |
622 | int t_ed_int(struct Timer *tim); | |
623 | ||
624 | Engines may find it convenient to associate an integer with a struct | |
625 | Timer. This macro may be used to retrieve that integer or, when used | |
626 | as an lvalue, to assign a value to it. Engine data must be either an | |
627 | int or a void*; use of both is prohibited. | |
628 | </function> | |
629 | ||
630 | <function> | |
631 | void* t_ed_ptr(struct Timer *tim); | |
632 | ||
633 | Engines may find it convenient to associate a void* pointer with a | |
634 | struct Timer. This macro may be used to retrieve that pointer or, | |
635 | when used as an lvalue, to assign a value to it. Engine data must be | |
636 | either an int or a void*; use of both is prohibited. | |
637 | </function> | |
638 | ||
639 | <function> | |
640 | int t_active(struct Timer *tim); | |
641 | ||
642 | A timer's active flag is set when initialized by timer_add(), and is | |
643 | cleared immediately prior to generating an event of type ET_DESTROY. | |
644 | This may be used by the application to determine whether or not the | |
645 | timer is still in use by the events subsystem. If it is, s_active() | |
646 | returns a non-zero value; otherwise, its value is 0. | |
647 | </function> | |
648 | ||
649 | <function> | |
650 | void timer_add(struct Timer* timer, EventCallBack call, void* data, | |
651 | enum TimerType type, time_t value); | |
652 | ||
653 | This function is called to initialize and queue a timer. The _timer_ | |
654 | parameter is a pointer to a struct Timer that is allocated by the | |
655 | application. The _call_ parameter is a pointer to a function to | |
656 | process the timer's expiration. The _data_ parameter is for use of | |
657 | the timer call-back and may be zero. The _type_ parameter must be one | |
658 | of the valid timer types--TT_ABSOLUTE, TT_RELATIVE, or TT_PERIODIC. | |
659 | Finally, _value_ is the value for the timer's expiration. | |
660 | </function> | |
661 | ||
662 | <function> | |
663 | void timer_del(struct Timer* timer); | |
664 | ||
665 | When the application no longer needs a TT_PERIODIC timer, or when it | |
666 | wishes to stop a TT_ABSOLUTE or TT_RELATIVE timer before its | |
667 | expiration, it should call the timer_del() function. | |
668 | </function> | |
669 | ||
670 | <function> | |
671 | void timer_chg(struct Timer* timer, enum TimerType type, time_t value); | |
672 | ||
673 | Occasionally, an application may wish to delay an existing TT_ABSOLUTE | |
674 | or TT_RELATIVE timer; this may be done with the timer_chg() function. | |
675 | The _type_ parameter must be one of TT_ABSOLUTE or | |
676 | TT_RELATIVE--changing the values of TT_PERIODIC timers is not | |
677 | supported. The _value_ parameter is the same as would be given to | |
678 | timer_add() for that particular type of timer. | |
679 | </function> | |
680 | ||
681 | <function> | |
682 | void timer_run(void); | |
683 | ||
684 | When an engine has finished processing the results of its socket and | |
685 | signal checks--just before it loops around to test for more events--it | |
686 | should call the timer_run() function to expire any waiting timers. | |
687 | </function> | |
688 | ||
689 | <function> | |
690 | time_t timer_next(struct Generators* gen); | |
691 | ||
692 | Most engines will use a blocking call with a timeout to check for | |
693 | socket activity. To determine when the next timer needs to be run, | |
694 | and thus to calculate how long the call should block, the engine | |
695 | should call timer_next() with the _gen_ parameter passed to the | |
696 | _EngineLoop_ function. The timer_next() function returns an absolute | |
697 | time, which may have to be massaged into a relative time before the | |
698 | engine may use it. | |
699 | </function> | |
700 | ||
701 | <function> | |
702 | const char* timer_to_name(enum TimerType type); | |
703 | ||
704 | This function is defined only when DEBUGMODE is #define'd. It takes | |
705 | the given _type_ and returns a string giving that type's name. This | |
706 | function may safely be called from Debug() macros. | |
707 | </function> | |
708 | ||
709 | <function> | |
710 | enum EventType ev_type(struct Event* ev); | |
711 | ||
712 | This macro simply returns the type of the event _ev_. | |
713 | </function> | |
714 | ||
715 | <function> | |
716 | int ev_data(struct Event* ev); | |
717 | ||
718 | When an event is generated, a single integer can be passed along as a | |
719 | piece of extra information. This can be used, for instance, to carry | |
720 | an errno value when an ET_ERROR is generated. This macro simply | |
721 | returns that integer. | |
722 | </function> | |
723 | ||
724 | <function> | |
725 | struct Socket* ev_socket(struct Event* ev); | |
726 | ||
727 | If the event was generated by a socket, this macro returns a pointer | |
728 | to the struct Socket that generated the event. The results are | |
729 | undefined if the event was not generated by a socket. | |
730 | </function> | |
731 | ||
732 | <function> | |
733 | struct Signal* ev_signal(struct Event* ev); | |
734 | ||
735 | If the event was generated by a signal, this macro returns a pointer | |
736 | to the struct Signal that generated the event. The results are | |
737 | undefined if the event was not generated by a signal. | |
738 | </function> | |
739 | ||
740 | <function> | |
741 | struct Timer* ev_timer(struct Event* ev); | |
742 | ||
743 | If the event was generated by a timer, this macro returns a pointer to | |
744 | the struct Timer that generated the event. The results are undefined | |
745 | if the event was not generated by a timer. | |
746 | </function> | |
747 | ||
748 | <function> | |
749 | void event_init(int max_sockets); | |
750 | ||
751 | Before any of the functions or macros described here can be called, | |
752 | the events subsystem must be initialized by calling event_init(). The | |
753 | _max_sockets_ parameter specifies to the events subsystem how many | |
754 | sockets it must be able to support; this figure may be used for memory | |
755 | allocation by the engines. | |
756 | </function> | |
757 | ||
758 | <function> | |
759 | void event_loop(void); | |
760 | ||
761 | Once the initial sockets are open, signals added, and timers queued, | |
762 | the application must call the event_loop() function in order to | |
763 | actually begin monitoring those sockets, signals, and timers. | |
764 | </function> | |
765 | ||
766 | <function> | |
767 | void event_generate(enum EventType type, void* arg, int data); | |
768 | ||
769 | This is the function called by the events subsystem to generate | |
770 | particular events. The _type_ parameter specifies the type of event | |
771 | to generate, and the _arg_ parameter must be a pointer to the event's | |
772 | generator. The _data_ parameter may be used for passing such things | |
773 | as signal numbers or errno values. | |
774 | </function> | |
775 | ||
776 | <function> | |
777 | const char* event_to_name(enum EventType type); | |
778 | ||
779 | This function is defined only when DEBUGMODE is #define'd. It takes | |
780 | the given _type_ and returns a string giving that event type's name. | |
781 | This function may safely be called from Debug() macros. | |
782 | </function> | |
783 | ||
784 | <function> | |
785 | const char* engine_name(void); | |
786 | ||
787 | This function is used to retrieve the name of the engine presently | |
788 | being used by the events subsystem. | |
789 | </function> | |
790 | ||
791 | <function> | |
792 | void gen_ref_inc(void* gen); | |
793 | ||
794 | This macro increments the reference count of the generator _gen_, | |
795 | preventing it from simply disappearing without warning. | |
796 | </function> | |
797 | ||
798 | <function> | |
799 | void gen_ref_dec(void* gen); | |
800 | ||
801 | This macro decrements the reference count of the generator _gen_, and | |
802 | releases the memory associated with it by generating at ET_DESTROY | |
803 | event if the reference count falls to zero and the generator is marked | |
804 | for destruction. No references should be made to the generator after | |
805 | calling this macro. | |
806 | </function> | |
807 | ||
808 | <authors> | |
809 | Kev <klmitch@mit.edu> | |
810 | </authors> | |
811 | ||
812 | <changelog> | |
813 | [2001-6-14 Kev] Finished initial description of the events subsystem. | |
814 | ||
815 | [2001-6-13 Kev] Initial description of the events subsystem. | |
816 | </changelog> |