OLD | NEW |
| (Empty) |
1 .\" $OpenBSD: event.3,v 1.4 2002/07/12 18:50:48 provos Exp $ | |
2 .\" | |
3 .\" Copyright (c) 2000 Artur Grabowski <art@openbsd.org> | |
4 .\" All rights reserved. | |
5 .\" | |
6 .\" Redistribution and use in source and binary forms, with or without | |
7 .\" modification, are permitted provided that the following conditions | |
8 .\" are met: | |
9 .\" | |
10 .\" 1. Redistributions of source code must retain the above copyright | |
11 .\" notice, this list of conditions and the following disclaimer. | |
12 .\" 2. Redistributions in binary form must reproduce the above copyright | |
13 .\" notice, this list of conditions and the following disclaimer in the | |
14 .\" documentation and/or other materials provided with the distribution. | |
15 .\" 3. The name of the author may not be used to endorse or promote products | |
16 .\" derived from this software without specific prior written permission. | |
17 .\" | |
18 .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | |
19 .\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | |
20 .\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |
21 .\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
22 .\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
23 .\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
24 .\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
25 .\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
26 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
27 .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 .\" | |
29 .Dd August 8, 2000 | |
30 .Dt EVENT 3 | |
31 .Os | |
32 .Sh NAME | |
33 .Nm event_init , | |
34 .Nm event_dispatch , | |
35 .Nm event_loop , | |
36 .Nm event_loopexit , | |
37 .Nm event_loopbreak , | |
38 .Nm event_set , | |
39 .Nm event_base_dispatch , | |
40 .Nm event_base_loop , | |
41 .Nm event_base_loopexit , | |
42 .Nm event_base_loopbreak , | |
43 .Nm event_base_set , | |
44 .Nm event_base_free , | |
45 .Nm event_add , | |
46 .Nm event_del , | |
47 .Nm event_once , | |
48 .Nm event_base_once , | |
49 .Nm event_pending , | |
50 .Nm event_initialized , | |
51 .Nm event_priority_init , | |
52 .Nm event_priority_set , | |
53 .Nm evtimer_set , | |
54 .Nm evtimer_add , | |
55 .Nm evtimer_del , | |
56 .Nm evtimer_pending , | |
57 .Nm evtimer_initialized , | |
58 .Nm signal_set , | |
59 .Nm signal_add , | |
60 .Nm signal_del , | |
61 .Nm signal_pending , | |
62 .Nm signal_initialized , | |
63 .Nm bufferevent_new , | |
64 .Nm bufferevent_free , | |
65 .Nm bufferevent_write , | |
66 .Nm bufferevent_write_buffer , | |
67 .Nm bufferevent_read , | |
68 .Nm bufferevent_enable , | |
69 .Nm bufferevent_disable , | |
70 .Nm bufferevent_settimeout , | |
71 .Nm bufferevent_base_set , | |
72 .Nm evbuffer_new , | |
73 .Nm evbuffer_free , | |
74 .Nm evbuffer_add , | |
75 .Nm evbuffer_add_buffer , | |
76 .Nm evbuffer_add_printf , | |
77 .Nm evbuffer_add_vprintf , | |
78 .Nm evbuffer_drain , | |
79 .Nm evbuffer_write , | |
80 .Nm evbuffer_read , | |
81 .Nm evbuffer_find , | |
82 .Nm evbuffer_readline , | |
83 .Nm evhttp_new , | |
84 .Nm evhttp_bind_socket , | |
85 .Nm evhttp_free | |
86 .Nd execute a function when a specific event occurs | |
87 .Sh SYNOPSIS | |
88 .Fd #include <sys/time.h> | |
89 .Fd #include <event.h> | |
90 .Ft "struct event_base *" | |
91 .Fn "event_init" "void" | |
92 .Ft int | |
93 .Fn "event_dispatch" "void" | |
94 .Ft int | |
95 .Fn "event_loop" "int flags" | |
96 .Ft int | |
97 .Fn "event_loopexit" "struct timeval *tv" | |
98 .Ft int | |
99 .Fn "event_loopbreak" "void" | |
100 .Ft void | |
101 .Fn "event_set" "struct event *ev" "int fd" "short event" "void (*fn)(int, short
, void *)" "void *arg" | |
102 .Ft int | |
103 .Fn "event_base_dispatch" "struct event_base *base" | |
104 .Ft int | |
105 .Fn "event_base_loop" "struct event_base *base" "int flags" | |
106 .Ft int | |
107 .Fn "event_base_loopexit" "struct event_base *base" "struct timeval *tv" | |
108 .Ft int | |
109 .Fn "event_base_loopbreak" "struct event_base *base" | |
110 .Ft int | |
111 .Fn "event_base_set" "struct event_base *base" "struct event *" | |
112 .Ft void | |
113 .Fn "event_base_free" "struct event_base *base" | |
114 .Ft int | |
115 .Fn "event_add" "struct event *ev" "struct timeval *tv" | |
116 .Ft int | |
117 .Fn "event_del" "struct event *ev" | |
118 .Ft int | |
119 .Fn "event_once" "int fd" "short event" "void (*fn)(int, short, void *)" "void *
arg" "struct timeval *tv" | |
120 .Ft int | |
121 .Fn "event_base_once" "struct event_base *base" "int fd" "short event" "void (*f
n)(int, short, void *)" "void *arg" "struct timeval *tv" | |
122 .Ft int | |
123 .Fn "event_pending" "struct event *ev" "short event" "struct timeval *tv" | |
124 .Ft int | |
125 .Fn "event_initialized" "struct event *ev" | |
126 .Ft int | |
127 .Fn "event_priority_init" "int npriorities" | |
128 .Ft int | |
129 .Fn "event_priority_set" "struct event *ev" "int priority" | |
130 .Ft void | |
131 .Fn "evtimer_set" "struct event *ev" "void (*fn)(int, short, void *)" "void *arg
" | |
132 .Ft void | |
133 .Fn "evtimer_add" "struct event *ev" "struct timeval *" | |
134 .Ft void | |
135 .Fn "evtimer_del" "struct event *ev" | |
136 .Ft int | |
137 .Fn "evtimer_pending" "struct event *ev" "struct timeval *tv" | |
138 .Ft int | |
139 .Fn "evtimer_initialized" "struct event *ev" | |
140 .Ft void | |
141 .Fn "signal_set" "struct event *ev" "int signal" "void (*fn)(int, short, void *)
" "void *arg" | |
142 .Ft void | |
143 .Fn "signal_add" "struct event *ev" "struct timeval *" | |
144 .Ft void | |
145 .Fn "signal_del" "struct event *ev" | |
146 .Ft int | |
147 .Fn "signal_pending" "struct event *ev" "struct timeval *tv" | |
148 .Ft int | |
149 .Fn "signal_initialized" "struct event *ev" | |
150 .Ft "struct bufferevent *" | |
151 .Fn "bufferevent_new" "int fd" "evbuffercb readcb" "evbuffercb writecb" "everror
cb" "void *cbarg" | |
152 .Ft void | |
153 .Fn "bufferevent_free" "struct bufferevent *bufev" | |
154 .Ft int | |
155 .Fn "bufferevent_write" "struct bufferevent *bufev" "void *data" "size_t size" | |
156 .Ft int | |
157 .Fn "bufferevent_write_buffer" "struct bufferevent *bufev" "struct evbuffer *buf
" | |
158 .Ft size_t | |
159 .Fn "bufferevent_read" "struct bufferevent *bufev" "void *data" "size_t size" | |
160 .Ft int | |
161 .Fn "bufferevent_enable" "struct bufferevent *bufev" "short event" | |
162 .Ft int | |
163 .Fn "bufferevent_disable" "struct bufferevent *bufev" "short event" | |
164 .Ft void | |
165 .Fn "bufferevent_settimeout" "struct bufferevent *bufev" "int timeout_read" "int
timeout_write" | |
166 .Ft int | |
167 .Fn "bufferevent_base_set" "struct event_base *base" "struct bufferevent *bufev" | |
168 .Ft "struct evbuffer *" | |
169 .Fn "evbuffer_new" "void" | |
170 .Ft void | |
171 .Fn "evbuffer_free" "struct evbuffer *buf" | |
172 .Ft int | |
173 .Fn "evbuffer_add" "struct evbuffer *buf" "const void *data" "size_t size" | |
174 .Ft int | |
175 .Fn "evbuffer_add_buffer" "struct evbuffer *dst" "struct evbuffer *src" | |
176 .Ft int | |
177 .Fn "evbuffer_add_printf" "struct evbuffer *buf" "const char *fmt" "..." | |
178 .Ft int | |
179 .Fn "evbuffer_add_vprintf" "struct evbuffer *buf" "const char *fmt" "va_list ap" | |
180 .Ft void | |
181 .Fn "evbuffer_drain" "struct evbuffer *buf" "size_t size" | |
182 .Ft int | |
183 .Fn "evbuffer_write" "struct evbuffer *buf" "int fd" | |
184 .Ft int | |
185 .Fn "evbuffer_read" "struct evbuffer *buf" "int fd" "int size" | |
186 .Ft "u_char *" | |
187 .Fn "evbuffer_find" "struct evbuffer *buf" "const u_char *data" "size_t size" | |
188 .Ft "char *" | |
189 .Fn "evbuffer_readline" "struct evbuffer *buf" | |
190 .Ft "struct evhttp *" | |
191 .Fn "evhttp_new" "struct event_base *base" | |
192 .Ft int | |
193 .Fn "evhttp_bind_socket" "struct evhttp *http" "const char *address" "u_short po
rt" | |
194 .Ft "void" | |
195 .Fn "evhttp_free" "struct evhttp *http" | |
196 .Ft int | |
197 .Fa (*event_sigcb)(void) ; | |
198 .Ft volatile sig_atomic_t | |
199 .Fa event_gotsig ; | |
200 .Sh DESCRIPTION | |
201 The | |
202 .Nm event | |
203 API provides a mechanism to execute a function when a specific event | |
204 on a file descriptor occurs or after a given time has passed. | |
205 .Pp | |
206 The | |
207 .Nm event | |
208 API needs to be initialized with | |
209 .Fn event_init | |
210 before it can be used. | |
211 .Pp | |
212 In order to process events, an application needs to call | |
213 .Fn event_dispatch . | |
214 This function only returns on error, and should replace the event core | |
215 of the application program. | |
216 .Pp | |
217 The function | |
218 .Fn event_set | |
219 prepares the event structure | |
220 .Fa ev | |
221 to be used in future calls to | |
222 .Fn event_add | |
223 and | |
224 .Fn event_del . | |
225 The event will be prepared to call the function specified by the | |
226 .Fa fn | |
227 argument with an | |
228 .Fa int | |
229 argument indicating the file descriptor, a | |
230 .Fa short | |
231 argument indicating the type of event, and a | |
232 .Fa void * | |
233 argument given in the | |
234 .Fa arg | |
235 argument. | |
236 The | |
237 .Fa fd | |
238 indicates the file descriptor that should be monitored for events. | |
239 The events can be either | |
240 .Va EV_READ , | |
241 .Va EV_WRITE , | |
242 or both, | |
243 indicating that an application can read or write from the file descriptor | |
244 respectively without blocking. | |
245 .Pp | |
246 The function | |
247 .Fa fn | |
248 will be called with the file descriptor that triggered the event and | |
249 the type of event which will be either | |
250 .Va EV_TIMEOUT , | |
251 .Va EV_SIGNAL , | |
252 .Va EV_READ , | |
253 or | |
254 .Va EV_WRITE . | |
255 Additionally, an event which has registered interest in more than one of the | |
256 preceeding events, via bitwise-OR to | |
257 .Fn event_set , | |
258 can provide its callback function with a bitwise-OR of more than one triggered | |
259 event. | |
260 The additional flag | |
261 .Va EV_PERSIST | |
262 makes an | |
263 .Fn event_add | |
264 persistent until | |
265 .Fn event_del | |
266 has been called. | |
267 .Pp | |
268 Once initialized, the | |
269 .Fa ev | |
270 structure can be used repeatedly with | |
271 .Fn event_add | |
272 and | |
273 .Fn event_del | |
274 and does not need to be reinitialized unless the function called and/or | |
275 the argument to it are to be changed. | |
276 However, when an | |
277 .Fa ev | |
278 structure has been added to libevent using | |
279 .Fn event_add | |
280 the structure must persist until the event occurs (assuming | |
281 .Fa EV_PERSIST | |
282 is not set) or is removed | |
283 using | |
284 .Fn event_del . | |
285 You may not reuse the same | |
286 .Fa ev | |
287 structure for multiple monitored descriptors; each descriptor | |
288 needs its own | |
289 .Fa ev . | |
290 .Pp | |
291 The function | |
292 .Fn event_add | |
293 schedules the execution of the | |
294 .Fa ev | |
295 event when the event specified in | |
296 .Fn event_set | |
297 occurs or in at least the time specified in the | |
298 .Fa tv . | |
299 If | |
300 .Fa tv | |
301 is | |
302 .Dv NULL , | |
303 no timeout occurs and the function will only be called | |
304 if a matching event occurs on the file descriptor. | |
305 The event in the | |
306 .Fa ev | |
307 argument must be already initialized by | |
308 .Fn event_set | |
309 and may not be used in calls to | |
310 .Fn event_set | |
311 until it has timed out or been removed with | |
312 .Fn event_del . | |
313 If the event in the | |
314 .Fa ev | |
315 argument already has a scheduled timeout, the old timeout will be | |
316 replaced by the new one. | |
317 .Pp | |
318 The function | |
319 .Fn event_del | |
320 will cancel the event in the argument | |
321 .Fa ev . | |
322 If the event has already executed or has never been added | |
323 the call will have no effect. | |
324 .Pp | |
325 The functions | |
326 .Fn evtimer_set , | |
327 .Fn evtimer_add , | |
328 .Fn evtimer_del , | |
329 .Fn evtimer_initialized , | |
330 and | |
331 .Fn evtimer_pending | |
332 are abbreviations for common situations where only a timeout is required. | |
333 The file descriptor passed will be \-1, and the event type will be | |
334 .Va EV_TIMEOUT . | |
335 .Pp | |
336 The functions | |
337 .Fn signal_set , | |
338 .Fn signal_add , | |
339 .Fn signal_del , | |
340 .Fn signal_initialized , | |
341 and | |
342 .Fn signal_pending | |
343 are abbreviations. | |
344 The event type will be a persistent | |
345 .Va EV_SIGNAL . | |
346 That means | |
347 .Fn signal_set | |
348 adds | |
349 .Va EV_PERSIST . | |
350 .Pp | |
351 In order to avoid races in signal handlers, the | |
352 .Nm event | |
353 API provides two variables: | |
354 .Va event_sigcb | |
355 and | |
356 .Va event_gotsig . | |
357 A signal handler | |
358 sets | |
359 .Va event_gotsig | |
360 to indicate that a signal has been received. | |
361 The application sets | |
362 .Va event_sigcb | |
363 to a callback function. | |
364 After the signal handler sets | |
365 .Va event_gotsig , | |
366 .Nm event_dispatch | |
367 will execute the callback function to process received signals. | |
368 The callback returns 1 when no events are registered any more. | |
369 It can return \-1 to indicate an error to the | |
370 .Nm event | |
371 library, causing | |
372 .Fn event_dispatch | |
373 to terminate with | |
374 .Va errno | |
375 set to | |
376 .Er EINTR . | |
377 .Pp | |
378 The function | |
379 .Fn event_once | |
380 is similar to | |
381 .Fn event_set . | |
382 However, it schedules a callback to be called exactly once and does not | |
383 require the caller to prepare an | |
384 .Fa event | |
385 structure. | |
386 This function supports | |
387 .Fa EV_TIMEOUT , | |
388 .Fa EV_READ , | |
389 and | |
390 .Fa EV_WRITE . | |
391 .Pp | |
392 The | |
393 .Fn event_pending | |
394 function can be used to check if the event specified by | |
395 .Fa event | |
396 is pending to run. | |
397 If | |
398 .Va EV_TIMEOUT | |
399 was specified and | |
400 .Fa tv | |
401 is not | |
402 .Dv NULL , | |
403 the expiration time of the event will be returned in | |
404 .Fa tv . | |
405 .Pp | |
406 The | |
407 .Fn event_initialized | |
408 macro can be used to check if an event has been initialized. | |
409 .Pp | |
410 The | |
411 .Nm event_loop | |
412 function provides an interface for single pass execution of pending | |
413 events. | |
414 The flags | |
415 .Va EVLOOP_ONCE | |
416 and | |
417 .Va EVLOOP_NONBLOCK | |
418 are recognized. | |
419 The | |
420 .Nm event_loopexit | |
421 function exits from the event loop. The next | |
422 .Fn event_loop | |
423 iteration after the | |
424 given timer expires will complete normally (handling all queued events) then | |
425 exit without blocking for events again. Subsequent invocations of | |
426 .Fn event_loop | |
427 will proceed normally. | |
428 The | |
429 .Nm event_loopbreak | |
430 function exits from the event loop immediately. | |
431 .Fn event_loop | |
432 will abort after the next event is completed; | |
433 .Fn event_loopbreak | |
434 is typically invoked from this event's callback. This behavior is analogous | |
435 to the "break;" statement. Subsequent invocations of | |
436 .Fn event_loop | |
437 will proceed normally. | |
438 .Pp | |
439 It is the responsibility of the caller to provide these functions with | |
440 pre-allocated event structures. | |
441 .Pp | |
442 .Sh EVENT PRIORITIES | |
443 By default | |
444 .Nm libevent | |
445 schedules all active events with the same priority. | |
446 However, sometimes it is desirable to process some events with a higher | |
447 priority than others. | |
448 For that reason, | |
449 .Nm libevent | |
450 supports strict priority queues. | |
451 Active events with a lower priority are always processed before events | |
452 with a higher priority. | |
453 .Pp | |
454 The number of different priorities can be set initially with the | |
455 .Fn event_priority_init | |
456 function. | |
457 This function should be called before the first call to | |
458 .Fn event_dispatch . | |
459 The | |
460 .Fn event_priority_set | |
461 function can be used to assign a priority to an event. | |
462 By default, | |
463 .Nm libevent | |
464 assigns the middle priority to all events unless their priority | |
465 is explicitly set. | |
466 .Sh THREAD SAFE EVENTS | |
467 .Nm Libevent | |
468 has experimental support for thread-safe events. | |
469 When initializing the library via | |
470 .Fn event_init , | |
471 an event base is returned. | |
472 This event base can be used in conjunction with calls to | |
473 .Fn event_base_set , | |
474 .Fn event_base_dispatch , | |
475 .Fn event_base_loop , | |
476 .Fn event_base_loopexit , | |
477 .Fn bufferevent_base_set | |
478 and | |
479 .Fn event_base_free . | |
480 .Fn event_base_set | |
481 should be called after preparing an event with | |
482 .Fn event_set , | |
483 as | |
484 .Fn event_set | |
485 assigns the provided event to the most recently created event base. | |
486 .Fn bufferevent_base_set | |
487 should be called after preparing a bufferevent with | |
488 .Fn bufferevent_new . | |
489 .Fn event_base_free | |
490 should be used to free memory associated with the event base | |
491 when it is no longer needed. | |
492 .Sh BUFFERED EVENTS | |
493 .Nm libevent | |
494 provides an abstraction on top of the regular event callbacks. | |
495 This abstraction is called a | |
496 .Va "buffered event" . | |
497 A buffered event provides input and output buffers that get filled | |
498 and drained automatically. | |
499 The user of a buffered event no longer deals directly with the IO, | |
500 but instead is reading from input and writing to output buffers. | |
501 .Pp | |
502 A new bufferevent is created by | |
503 .Fn bufferevent_new . | |
504 The parameter | |
505 .Fa fd | |
506 specifies the file descriptor from which data is read and written to. | |
507 This file descriptor is not allowed to be a | |
508 .Xr pipe 2 . | |
509 The next three parameters are callbacks. | |
510 The read and write callback have the following form: | |
511 .Ft void | |
512 .Fn "(*cb)" "struct bufferevent *bufev" "void *arg" . | |
513 The error callback has the following form: | |
514 .Ft void | |
515 .Fn "(*cb)" "struct bufferevent *bufev" "short what" "void *arg" . | |
516 The argument is specified by the fourth parameter | |
517 .Fa "cbarg" . | |
518 A | |
519 .Fa bufferevent struct | |
520 pointer is returned on success, NULL on error. | |
521 Both the read and the write callback may be NULL. | |
522 The error callback has to be always provided. | |
523 .Pp | |
524 Once initialized, the bufferevent structure can be used repeatedly with | |
525 bufferevent_enable() and bufferevent_disable(). | |
526 The flags parameter can be a combination of | |
527 .Va EV_READ | |
528 and | |
529 .Va EV_WRITE . | |
530 When read enabled the bufferevent will try to read from the file | |
531 descriptor and call the read callback. | |
532 The write callback is executed | |
533 whenever the output buffer is drained below the write low watermark, | |
534 which is | |
535 .Va 0 | |
536 by default. | |
537 .Pp | |
538 The | |
539 .Fn bufferevent_write | |
540 function can be used to write data to the file descriptor. | |
541 The data is appended to the output buffer and written to the descriptor | |
542 automatically as it becomes available for writing. | |
543 .Fn bufferevent_write | |
544 returns 0 on success or \-1 on failure. | |
545 The | |
546 .Fn bufferevent_read | |
547 function is used to read data from the input buffer, | |
548 returning the amount of data read. | |
549 .Pp | |
550 If multiple bases are in use, bufferevent_base_set() must be called before | |
551 enabling the bufferevent for the first time. | |
552 .Sh NON-BLOCKING HTTP SUPPORT | |
553 .Nm libevent | |
554 provides a very thin HTTP layer that can be used both to host an HTTP | |
555 server and also to make HTTP requests. | |
556 An HTTP server can be created by calling | |
557 .Fn evhttp_new . | |
558 It can be bound to any port and address with the | |
559 .Fn evhttp_bind_socket | |
560 function. | |
561 When the HTTP server is no longer used, it can be freed via | |
562 .Fn evhttp_free . | |
563 .Pp | |
564 To be notified of HTTP requests, a user needs to register callbacks with the | |
565 HTTP server. | |
566 This can be done by calling | |
567 .Fn evhttp_set_cb . | |
568 The second argument is the URI for which a callback is being registered. | |
569 The corresponding callback will receive an | |
570 .Va struct evhttp_request | |
571 object that contains all information about the request. | |
572 .Pp | |
573 This section does not document all the possible function calls; please | |
574 check | |
575 .Va event.h | |
576 for the public interfaces. | |
577 .Sh ADDITIONAL NOTES | |
578 It is possible to disable support for | |
579 .Va epoll , kqueue , devpoll , poll | |
580 or | |
581 .Va select | |
582 by setting the environment variable | |
583 .Va EVENT_NOEPOLL , EVENT_NOKQUEUE , EVENT_NODEVPOLL , EVENT_NOPOLL | |
584 or | |
585 .Va EVENT_NOSELECT , | |
586 respectively. | |
587 By setting the environment variable | |
588 .Va EVENT_SHOW_METHOD , | |
589 .Nm libevent | |
590 displays the kernel notification method that it uses. | |
591 .Sh RETURN VALUES | |
592 Upon successful completion | |
593 .Fn event_add | |
594 and | |
595 .Fn event_del | |
596 return 0. | |
597 Otherwise, \-1 is returned and the global variable errno is | |
598 set to indicate the error. | |
599 .Sh SEE ALSO | |
600 .Xr kqueue 2 , | |
601 .Xr poll 2 , | |
602 .Xr select 2 , | |
603 .Xr evdns 3 , | |
604 .Xr timeout 9 | |
605 .Sh HISTORY | |
606 The | |
607 .Nm event | |
608 API manpage is based on the | |
609 .Xr timeout 9 | |
610 manpage by Artur Grabowski. | |
611 The port of | |
612 .Nm libevent | |
613 to Windows is due to Michael A. Davis. | |
614 Support for real-time signals is due to Taral. | |
615 .Sh AUTHORS | |
616 The | |
617 .Nm event | |
618 library was written by Niels Provos. | |
619 .Sh BUGS | |
620 This documentation is neither complete nor authoritative. | |
621 If you are in doubt about the usage of this API then | |
622 check the source code to find out how it works, write | |
623 up the missing piece of documentation and send it to | |
624 me for inclusion in this man page. | |
OLD | NEW |