|  | .\"	$OpenBSD: event.3,v 1.4 2002/07/12 18:50:48 provos Exp $ | 
|  | .\" | 
|  | .\" Copyright (c) 2000 Artur Grabowski <art@openbsd.org> | 
|  | .\" All rights reserved. | 
|  | .\" | 
|  | .\" Redistribution and use in source and binary forms, with or without | 
|  | .\" modification, are permitted provided that the following conditions | 
|  | .\" are met: | 
|  | .\" | 
|  | .\" 1. Redistributions of source code must retain the above copyright | 
|  | .\"    notice, this list of conditions and the following disclaimer. | 
|  | .\" 2. Redistributions in binary form must reproduce the above copyright | 
|  | .\"    notice, this list of conditions and the following disclaimer in the | 
|  | .\"    documentation and/or other materials provided with the distribution. | 
|  | .\" 3. The name of the author may not be used to endorse or promote products | 
|  | .\"    derived from this software without specific prior written permission. | 
|  | .\" | 
|  | .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | 
|  | .\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | 
|  | .\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | 
|  | .\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 
|  | .\" EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
|  | .\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | 
|  | .\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 
|  | .\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | 
|  | .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | 
|  | .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | .\" | 
|  | .Dd August 8, 2000 | 
|  | .Dt EVENT 3 | 
|  | .Os | 
|  | .Sh NAME | 
|  | .Nm event_init , | 
|  | .Nm event_dispatch , | 
|  | .Nm event_loop , | 
|  | .Nm event_loopexit , | 
|  | .Nm event_loopbreak , | 
|  | .Nm event_set , | 
|  | .Nm event_base_dispatch , | 
|  | .Nm event_base_loop , | 
|  | .Nm event_base_loopexit , | 
|  | .Nm event_base_loopbreak , | 
|  | .Nm event_base_set , | 
|  | .Nm event_base_free , | 
|  | .Nm event_add , | 
|  | .Nm event_del , | 
|  | .Nm event_once , | 
|  | .Nm event_base_once , | 
|  | .Nm event_pending , | 
|  | .Nm event_initialized , | 
|  | .Nm event_priority_init , | 
|  | .Nm event_priority_set , | 
|  | .Nm evtimer_set , | 
|  | .Nm evtimer_add , | 
|  | .Nm evtimer_del , | 
|  | .Nm evtimer_pending , | 
|  | .Nm evtimer_initialized , | 
|  | .Nm signal_set , | 
|  | .Nm signal_add , | 
|  | .Nm signal_del , | 
|  | .Nm signal_pending , | 
|  | .Nm signal_initialized , | 
|  | .Nm bufferevent_new , | 
|  | .Nm bufferevent_free , | 
|  | .Nm bufferevent_write , | 
|  | .Nm bufferevent_write_buffer , | 
|  | .Nm bufferevent_read , | 
|  | .Nm bufferevent_enable , | 
|  | .Nm bufferevent_disable , | 
|  | .Nm bufferevent_settimeout , | 
|  | .Nm bufferevent_base_set , | 
|  | .Nm evbuffer_new , | 
|  | .Nm evbuffer_free , | 
|  | .Nm evbuffer_add , | 
|  | .Nm evbuffer_add_buffer , | 
|  | .Nm evbuffer_add_printf , | 
|  | .Nm evbuffer_add_vprintf , | 
|  | .Nm evbuffer_drain , | 
|  | .Nm evbuffer_write , | 
|  | .Nm evbuffer_read , | 
|  | .Nm evbuffer_find , | 
|  | .Nm evbuffer_readline , | 
|  | .Nm evhttp_new , | 
|  | .Nm evhttp_bind_socket , | 
|  | .Nm evhttp_free | 
|  | .Nd execute a function when a specific event occurs | 
|  | .Sh SYNOPSIS | 
|  | .Fd #include <sys/time.h> | 
|  | .Fd #include <event.h> | 
|  | .Ft "struct event_base *" | 
|  | .Fn "event_init" "void" | 
|  | .Ft int | 
|  | .Fn "event_dispatch" "void" | 
|  | .Ft int | 
|  | .Fn "event_loop" "int flags" | 
|  | .Ft int | 
|  | .Fn "event_loopexit" "struct timeval *tv" | 
|  | .Ft int | 
|  | .Fn "event_loopbreak" "void" | 
|  | .Ft void | 
|  | .Fn "event_set" "struct event *ev" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" | 
|  | .Ft int | 
|  | .Fn "event_base_dispatch" "struct event_base *base" | 
|  | .Ft int | 
|  | .Fn "event_base_loop" "struct event_base *base" "int flags" | 
|  | .Ft int | 
|  | .Fn "event_base_loopexit" "struct event_base *base" "struct timeval *tv" | 
|  | .Ft int | 
|  | .Fn "event_base_loopbreak" "struct event_base *base" | 
|  | .Ft int | 
|  | .Fn "event_base_set" "struct event_base *base" "struct event *" | 
|  | .Ft void | 
|  | .Fn "event_base_free" "struct event_base *base" | 
|  | .Ft int | 
|  | .Fn "event_add" "struct event *ev" "struct timeval *tv" | 
|  | .Ft int | 
|  | .Fn "event_del" "struct event *ev" | 
|  | .Ft int | 
|  | .Fn "event_once" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "struct timeval *tv" | 
|  | .Ft int | 
|  | .Fn "event_base_once" "struct event_base *base" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "struct timeval *tv" | 
|  | .Ft int | 
|  | .Fn "event_pending" "struct event *ev" "short event" "struct timeval *tv" | 
|  | .Ft int | 
|  | .Fn "event_initialized" "struct event *ev" | 
|  | .Ft int | 
|  | .Fn "event_priority_init" "int npriorities" | 
|  | .Ft int | 
|  | .Fn "event_priority_set" "struct event *ev" "int priority" | 
|  | .Ft void | 
|  | .Fn "evtimer_set" "struct event *ev" "void (*fn)(int, short, void *)" "void *arg" | 
|  | .Ft void | 
|  | .Fn "evtimer_add" "struct event *ev" "struct timeval *" | 
|  | .Ft void | 
|  | .Fn "evtimer_del" "struct event *ev" | 
|  | .Ft int | 
|  | .Fn "evtimer_pending" "struct event *ev" "struct timeval *tv" | 
|  | .Ft int | 
|  | .Fn "evtimer_initialized" "struct event *ev" | 
|  | .Ft void | 
|  | .Fn "signal_set" "struct event *ev" "int signal" "void (*fn)(int, short, void *)" "void *arg" | 
|  | .Ft void | 
|  | .Fn "signal_add" "struct event *ev" "struct timeval *" | 
|  | .Ft void | 
|  | .Fn "signal_del" "struct event *ev" | 
|  | .Ft int | 
|  | .Fn "signal_pending" "struct event *ev" "struct timeval *tv" | 
|  | .Ft int | 
|  | .Fn "signal_initialized" "struct event *ev" | 
|  | .Ft "struct bufferevent *" | 
|  | .Fn "bufferevent_new" "int fd" "evbuffercb readcb" "evbuffercb writecb" "everrorcb" "void *cbarg" | 
|  | .Ft void | 
|  | .Fn "bufferevent_free" "struct bufferevent *bufev" | 
|  | .Ft int | 
|  | .Fn "bufferevent_write" "struct bufferevent *bufev" "void *data" "size_t size" | 
|  | .Ft int | 
|  | .Fn "bufferevent_write_buffer" "struct bufferevent *bufev" "struct evbuffer *buf" | 
|  | .Ft size_t | 
|  | .Fn "bufferevent_read" "struct bufferevent *bufev" "void *data" "size_t size" | 
|  | .Ft int | 
|  | .Fn "bufferevent_enable" "struct bufferevent *bufev" "short event" | 
|  | .Ft int | 
|  | .Fn "bufferevent_disable" "struct bufferevent *bufev" "short event" | 
|  | .Ft void | 
|  | .Fn "bufferevent_settimeout" "struct bufferevent *bufev" "int timeout_read" "int timeout_write" | 
|  | .Ft int | 
|  | .Fn "bufferevent_base_set" "struct event_base *base" "struct bufferevent *bufev" | 
|  | .Ft "struct evbuffer *" | 
|  | .Fn "evbuffer_new" "void" | 
|  | .Ft void | 
|  | .Fn "evbuffer_free" "struct evbuffer *buf" | 
|  | .Ft int | 
|  | .Fn "evbuffer_add" "struct evbuffer *buf" "const void *data" "size_t size" | 
|  | .Ft int | 
|  | .Fn "evbuffer_add_buffer" "struct evbuffer *dst" "struct evbuffer *src" | 
|  | .Ft int | 
|  | .Fn "evbuffer_add_printf" "struct evbuffer *buf" "const char *fmt" "..." | 
|  | .Ft int | 
|  | .Fn "evbuffer_add_vprintf" "struct evbuffer *buf" "const char *fmt" "va_list ap" | 
|  | .Ft void | 
|  | .Fn "evbuffer_drain" "struct evbuffer *buf" "size_t size" | 
|  | .Ft int | 
|  | .Fn "evbuffer_write" "struct evbuffer *buf" "int fd" | 
|  | .Ft int | 
|  | .Fn "evbuffer_read" "struct evbuffer *buf" "int fd" "int size" | 
|  | .Ft "u_char *" | 
|  | .Fn "evbuffer_find" "struct evbuffer *buf" "const u_char *data" "size_t size" | 
|  | .Ft "char *" | 
|  | .Fn "evbuffer_readline" "struct evbuffer *buf" | 
|  | .Ft "struct evhttp *" | 
|  | .Fn "evhttp_new" "struct event_base *base" | 
|  | .Ft int | 
|  | .Fn "evhttp_bind_socket" "struct evhttp *http" "const char *address" "u_short port" | 
|  | .Ft "void" | 
|  | .Fn "evhttp_free" "struct evhttp *http" | 
|  | .Ft int | 
|  | .Fa (*event_sigcb)(void) ; | 
|  | .Ft volatile sig_atomic_t | 
|  | .Fa event_gotsig ; | 
|  | .Sh DESCRIPTION | 
|  | The | 
|  | .Nm event | 
|  | API provides a mechanism to execute a function when a specific event | 
|  | on a file descriptor occurs or after a given time has passed. | 
|  | .Pp | 
|  | The | 
|  | .Nm event | 
|  | API needs to be initialized with | 
|  | .Fn event_init | 
|  | before it can be used. | 
|  | .Pp | 
|  | In order to process events, an application needs to call | 
|  | .Fn event_dispatch . | 
|  | This function only returns on error, and should replace the event core | 
|  | of the application program. | 
|  | .Pp | 
|  | The function | 
|  | .Fn event_set | 
|  | prepares the event structure | 
|  | .Fa ev | 
|  | to be used in future calls to | 
|  | .Fn event_add | 
|  | and | 
|  | .Fn event_del . | 
|  | The event will be prepared to call the function specified by the | 
|  | .Fa fn | 
|  | argument with an | 
|  | .Fa int | 
|  | argument indicating the file descriptor, a | 
|  | .Fa short | 
|  | argument indicating the type of event, and a | 
|  | .Fa void * | 
|  | argument given in the | 
|  | .Fa arg | 
|  | argument. | 
|  | The | 
|  | .Fa fd | 
|  | indicates the file descriptor that should be monitored for events. | 
|  | The events can be either | 
|  | .Va EV_READ , | 
|  | .Va EV_WRITE , | 
|  | or both, | 
|  | indicating that an application can read or write from the file descriptor | 
|  | respectively without blocking. | 
|  | .Pp | 
|  | The function | 
|  | .Fa fn | 
|  | will be called with the file descriptor that triggered the event and | 
|  | the type of event which will be either | 
|  | .Va EV_TIMEOUT , | 
|  | .Va EV_SIGNAL , | 
|  | .Va EV_READ , | 
|  | or | 
|  | .Va EV_WRITE . | 
|  | Additionally, an event which has registered interest in more than one of the | 
|  | preceeding events, via bitwise-OR to | 
|  | .Fn event_set , | 
|  | can provide its callback function with a bitwise-OR of more than one triggered | 
|  | event. | 
|  | The additional flag | 
|  | .Va EV_PERSIST | 
|  | makes an | 
|  | .Fn event_add | 
|  | persistent until | 
|  | .Fn event_del | 
|  | has been called. | 
|  | .Pp | 
|  | Once initialized, the | 
|  | .Fa ev | 
|  | structure can be used repeatedly with | 
|  | .Fn event_add | 
|  | and | 
|  | .Fn event_del | 
|  | and does not need to be reinitialized unless the function called and/or | 
|  | the argument to it are to be changed. | 
|  | However, when an | 
|  | .Fa ev | 
|  | structure has been added to libevent using | 
|  | .Fn event_add | 
|  | the structure must persist until the event occurs (assuming | 
|  | .Fa EV_PERSIST | 
|  | is not set) or is removed | 
|  | using | 
|  | .Fn event_del . | 
|  | You may not reuse the same | 
|  | .Fa ev | 
|  | structure for multiple monitored descriptors; each descriptor | 
|  | needs its own | 
|  | .Fa ev . | 
|  | .Pp | 
|  | The function | 
|  | .Fn event_add | 
|  | schedules the execution of the | 
|  | .Fa ev | 
|  | event when the event specified in | 
|  | .Fn event_set | 
|  | occurs or in at least the time specified in the | 
|  | .Fa tv . | 
|  | If | 
|  | .Fa tv | 
|  | is | 
|  | .Dv NULL , | 
|  | no timeout occurs and the function will only be called | 
|  | if a matching event occurs on the file descriptor. | 
|  | The event in the | 
|  | .Fa ev | 
|  | argument must be already initialized by | 
|  | .Fn event_set | 
|  | and may not be used in calls to | 
|  | .Fn event_set | 
|  | until it has timed out or been removed with | 
|  | .Fn event_del . | 
|  | If the event in the | 
|  | .Fa ev | 
|  | argument already has a scheduled timeout, the old timeout will be | 
|  | replaced by the new one. | 
|  | .Pp | 
|  | The function | 
|  | .Fn event_del | 
|  | will cancel the event in the argument | 
|  | .Fa ev . | 
|  | If the event has already executed or has never been added | 
|  | the call will have no effect. | 
|  | .Pp | 
|  | The functions | 
|  | .Fn evtimer_set , | 
|  | .Fn evtimer_add , | 
|  | .Fn evtimer_del , | 
|  | .Fn evtimer_initialized , | 
|  | and | 
|  | .Fn evtimer_pending | 
|  | are abbreviations for common situations where only a timeout is required. | 
|  | The file descriptor passed will be \-1, and the event type will be | 
|  | .Va EV_TIMEOUT . | 
|  | .Pp | 
|  | The functions | 
|  | .Fn signal_set , | 
|  | .Fn signal_add , | 
|  | .Fn signal_del , | 
|  | .Fn signal_initialized , | 
|  | and | 
|  | .Fn signal_pending | 
|  | are abbreviations. | 
|  | The event type will be a persistent | 
|  | .Va EV_SIGNAL . | 
|  | That means | 
|  | .Fn signal_set | 
|  | adds | 
|  | .Va EV_PERSIST . | 
|  | .Pp | 
|  | In order to avoid races in signal handlers, the | 
|  | .Nm event | 
|  | API provides two variables: | 
|  | .Va event_sigcb | 
|  | and | 
|  | .Va event_gotsig . | 
|  | A signal handler | 
|  | sets | 
|  | .Va event_gotsig | 
|  | to indicate that a signal has been received. | 
|  | The application sets | 
|  | .Va event_sigcb | 
|  | to a callback function. | 
|  | After the signal handler sets | 
|  | .Va event_gotsig , | 
|  | .Nm event_dispatch | 
|  | will execute the callback function to process received signals. | 
|  | The callback returns 1 when no events are registered any more. | 
|  | It can return \-1 to indicate an error to the | 
|  | .Nm event | 
|  | library, causing | 
|  | .Fn event_dispatch | 
|  | to terminate with | 
|  | .Va errno | 
|  | set to | 
|  | .Er EINTR . | 
|  | .Pp | 
|  | The function | 
|  | .Fn event_once | 
|  | is similar to | 
|  | .Fn event_set . | 
|  | However, it schedules a callback to be called exactly once and does not | 
|  | require the caller to prepare an | 
|  | .Fa event | 
|  | structure. | 
|  | This function supports | 
|  | .Fa EV_TIMEOUT , | 
|  | .Fa EV_READ , | 
|  | and | 
|  | .Fa EV_WRITE . | 
|  | .Pp | 
|  | The | 
|  | .Fn event_pending | 
|  | function can be used to check if the event specified by | 
|  | .Fa event | 
|  | is pending to run. | 
|  | If | 
|  | .Va EV_TIMEOUT | 
|  | was specified and | 
|  | .Fa tv | 
|  | is not | 
|  | .Dv NULL , | 
|  | the expiration time of the event will be returned in | 
|  | .Fa tv . | 
|  | .Pp | 
|  | The | 
|  | .Fn event_initialized | 
|  | macro can be used to check if an event has been initialized. | 
|  | .Pp | 
|  | The | 
|  | .Nm event_loop | 
|  | function provides an interface for single pass execution of pending | 
|  | events. | 
|  | The flags | 
|  | .Va EVLOOP_ONCE | 
|  | and | 
|  | .Va EVLOOP_NONBLOCK | 
|  | are recognized. | 
|  | The | 
|  | .Nm event_loopexit | 
|  | function exits from the event loop. The next | 
|  | .Fn event_loop | 
|  | iteration after the | 
|  | given timer expires will complete normally (handling all queued events) then | 
|  | exit without blocking for events again. Subsequent invocations of | 
|  | .Fn event_loop | 
|  | will proceed normally. | 
|  | The | 
|  | .Nm event_loopbreak | 
|  | function exits from the event loop immediately. | 
|  | .Fn event_loop | 
|  | will abort after the next event is completed; | 
|  | .Fn event_loopbreak | 
|  | is typically invoked from this event's callback. This behavior is analogous | 
|  | to the "break;" statement. Subsequent invocations of | 
|  | .Fn event_loop | 
|  | will proceed normally. | 
|  | .Pp | 
|  | It is the responsibility of the caller to provide these functions with | 
|  | pre-allocated event structures. | 
|  | .Pp | 
|  | .Sh EVENT PRIORITIES | 
|  | By default | 
|  | .Nm libevent | 
|  | schedules all active events with the same priority. | 
|  | However, sometimes it is desirable to process some events with a higher | 
|  | priority than others. | 
|  | For that reason, | 
|  | .Nm libevent | 
|  | supports strict priority queues. | 
|  | Active events with a lower priority are always processed before events | 
|  | with a higher priority. | 
|  | .Pp | 
|  | The number of different priorities can be set initially with the | 
|  | .Fn event_priority_init | 
|  | function. | 
|  | This function should be called before the first call to | 
|  | .Fn event_dispatch . | 
|  | The | 
|  | .Fn event_priority_set | 
|  | function can be used to assign a priority to an event. | 
|  | By default, | 
|  | .Nm libevent | 
|  | assigns the middle priority to all events unless their priority | 
|  | is explicitly set. | 
|  | .Sh THREAD SAFE EVENTS | 
|  | .Nm Libevent | 
|  | has experimental support for thread-safe events. | 
|  | When initializing the library via | 
|  | .Fn event_init , | 
|  | an event base is returned. | 
|  | This event base can be used in conjunction with calls to | 
|  | .Fn event_base_set , | 
|  | .Fn event_base_dispatch , | 
|  | .Fn event_base_loop , | 
|  | .Fn event_base_loopexit , | 
|  | .Fn bufferevent_base_set | 
|  | and | 
|  | .Fn event_base_free . | 
|  | .Fn event_base_set | 
|  | should be called after preparing an event with | 
|  | .Fn event_set , | 
|  | as | 
|  | .Fn event_set | 
|  | assigns the provided event to the most recently created event base. | 
|  | .Fn bufferevent_base_set | 
|  | should be called after preparing a bufferevent with | 
|  | .Fn bufferevent_new . | 
|  | .Fn event_base_free | 
|  | should be used to free memory associated with the event base | 
|  | when it is no longer needed. | 
|  | .Sh BUFFERED EVENTS | 
|  | .Nm libevent | 
|  | provides an abstraction on top of the regular event callbacks. | 
|  | This abstraction is called a | 
|  | .Va "buffered event" . | 
|  | A buffered event provides input and output buffers that get filled | 
|  | and drained automatically. | 
|  | The user of a buffered event no longer deals directly with the IO, | 
|  | but instead is reading from input and writing to output buffers. | 
|  | .Pp | 
|  | A new bufferevent is created by | 
|  | .Fn bufferevent_new . | 
|  | The parameter | 
|  | .Fa fd | 
|  | specifies the file descriptor from which data is read and written to. | 
|  | This file descriptor is not allowed to be a | 
|  | .Xr pipe 2 . | 
|  | The next three parameters are callbacks. | 
|  | The read and write callback have the following form: | 
|  | .Ft void | 
|  | .Fn "(*cb)" "struct bufferevent *bufev" "void *arg" . | 
|  | The error callback has the following form: | 
|  | .Ft void | 
|  | .Fn "(*cb)" "struct bufferevent *bufev" "short what" "void *arg" . | 
|  | The argument is specified by the fourth parameter | 
|  | .Fa "cbarg" . | 
|  | A | 
|  | .Fa bufferevent struct | 
|  | pointer is returned on success, NULL on error. | 
|  | Both the read and the write callback may be NULL. | 
|  | The error callback has to be always provided. | 
|  | .Pp | 
|  | Once initialized, the bufferevent structure can be used repeatedly with | 
|  | bufferevent_enable() and bufferevent_disable(). | 
|  | The flags parameter can be a combination of | 
|  | .Va EV_READ | 
|  | and | 
|  | .Va EV_WRITE . | 
|  | When read enabled the bufferevent will try to read from the file | 
|  | descriptor and call the read callback. | 
|  | The write callback is executed | 
|  | whenever the output buffer is drained below the write low watermark, | 
|  | which is | 
|  | .Va 0 | 
|  | by default. | 
|  | .Pp | 
|  | The | 
|  | .Fn bufferevent_write | 
|  | function can be used to write data to the file descriptor. | 
|  | The data is appended to the output buffer and written to the descriptor | 
|  | automatically as it becomes available for writing. | 
|  | .Fn bufferevent_write | 
|  | returns 0 on success or \-1 on failure. | 
|  | The | 
|  | .Fn bufferevent_read | 
|  | function is used to read data from the input buffer, | 
|  | returning the amount of data read. | 
|  | .Pp | 
|  | If multiple bases are in use, bufferevent_base_set() must be called before | 
|  | enabling the bufferevent for the first time. | 
|  | .Sh NON-BLOCKING HTTP SUPPORT | 
|  | .Nm libevent | 
|  | provides a very thin HTTP layer that can be used both to host an HTTP | 
|  | server and also to make HTTP requests. | 
|  | An HTTP server can be created by calling | 
|  | .Fn evhttp_new . | 
|  | It can be bound to any port and address with the | 
|  | .Fn evhttp_bind_socket | 
|  | function. | 
|  | When the HTTP server is no longer used, it can be freed via | 
|  | .Fn evhttp_free . | 
|  | .Pp | 
|  | To be notified of HTTP requests, a user needs to register callbacks with the | 
|  | HTTP server. | 
|  | This can be done by calling | 
|  | .Fn evhttp_set_cb . | 
|  | The second argument is the URI for which a callback is being registered. | 
|  | The corresponding callback will receive an | 
|  | .Va struct evhttp_request | 
|  | object that contains all information about the request. | 
|  | .Pp | 
|  | This section does not document all the possible function calls; please | 
|  | check | 
|  | .Va event.h | 
|  | for the public interfaces. | 
|  | .Sh ADDITIONAL NOTES | 
|  | It is possible to disable support for | 
|  | .Va epoll , kqueue , devpoll , poll | 
|  | or | 
|  | .Va select | 
|  | by setting the environment variable | 
|  | .Va EVENT_NOEPOLL , EVENT_NOKQUEUE , EVENT_NODEVPOLL , EVENT_NOPOLL | 
|  | or | 
|  | .Va EVENT_NOSELECT , | 
|  | respectively. | 
|  | By setting the environment variable | 
|  | .Va EVENT_SHOW_METHOD , | 
|  | .Nm libevent | 
|  | displays the kernel notification method that it uses. | 
|  | .Sh RETURN VALUES | 
|  | Upon successful completion | 
|  | .Fn event_add | 
|  | and | 
|  | .Fn event_del | 
|  | return 0. | 
|  | Otherwise, \-1 is returned and the global variable errno is | 
|  | set to indicate the error. | 
|  | .Sh SEE ALSO | 
|  | .Xr kqueue 2 , | 
|  | .Xr poll 2 , | 
|  | .Xr select 2 , | 
|  | .Xr evdns 3 , | 
|  | .Xr timeout 9 | 
|  | .Sh HISTORY | 
|  | The | 
|  | .Nm event | 
|  | API manpage is based on the | 
|  | .Xr timeout 9 | 
|  | manpage by Artur Grabowski. | 
|  | The port of | 
|  | .Nm libevent | 
|  | to Windows is due to Michael A. Davis. | 
|  | Support for real-time signals is due to Taral. | 
|  | .Sh AUTHORS | 
|  | The | 
|  | .Nm event | 
|  | library was written by Niels Provos. | 
|  | .Sh BUGS | 
|  | This documentation is neither complete nor authoritative. | 
|  | If you are in doubt about the usage of this API then | 
|  | check the source code to find out how it works, write | 
|  | up the missing piece of documentation and send it to | 
|  | me for inclusion in this man page. |