008312679d
Reviewed By: wiz
507 lines
13 KiB
Groff
507 lines
13 KiB
Groff
.\" $NetBSD: event.3,v 1.10 2006/10/15 01:53:41 uebayasi Exp $
|
|
.\" $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 April 17, 2005
|
|
.Dt EVENT 3
|
|
.Os
|
|
.Sh NAME
|
|
.Nm event_init ,
|
|
.Nm event_dispatch ,
|
|
.Nm event_loop ,
|
|
.Nm event_loopexit ,
|
|
.Nm event_base_loop ,
|
|
.Nm event_base_loopexit ,
|
|
.Nm event_set ,
|
|
.Nm event_add ,
|
|
.Nm event_del ,
|
|
.Nm event_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 evbuffer_new ,
|
|
.Nm evbuffer_free ,
|
|
.Nm evbuffer_add ,
|
|
.Nm evbuffer_add_buffer ,
|
|
.Nm evbuffer_add_printf ,
|
|
.Nm evbuffer_drain ,
|
|
.Nm evbuffer_write ,
|
|
.Nm evbuffer_read ,
|
|
.Nm evbuffer_find
|
|
.Nd execute a function when a specific event occurs
|
|
.Sh LIBRARY
|
|
.Lb libevent
|
|
.Sh SYNOPSIS
|
|
.In sys/time.h
|
|
.In event.h
|
|
.Ft void
|
|
.Fn event_init
|
|
.Ft int
|
|
.Fn event_dispatch
|
|
.Ft int
|
|
.Fn event_loop "int flags"
|
|
.Ft int
|
|
.Fn event_loopexit "struct timeval *tv"
|
|
.Ft void
|
|
.Fn event_set "struct event *ev" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg"
|
|
.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_pending "struct event *ev" "short event" "struct timeval *tv"
|
|
.Ft int
|
|
.Fn event_initialized "struct event *ev"
|
|
.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 *tv"
|
|
.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 *tv"
|
|
.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 "struct evbuffer *"
|
|
.Fn evbuffer_new "void"
|
|
.Ft void
|
|
.Fn evbuffer_free "struct evbuffer *buf"
|
|
.Ft int
|
|
.Fn evbuffer_add "struct evbuffer *buf" "u_char *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" "char *fmt" "..."
|
|
.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" "u_char *data" "size_t size"
|
|
.Ft int
|
|
.Fn "(*event_sigcb)" "void"
|
|
.Ft int
|
|
.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
|
|
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
|
|
.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 allows the loop to be terminated after some amount of time
|
|
has passed.
|
|
The parameter indicates the time after which the loop should terminate.
|
|
.Pp
|
|
It is the responsibility of the caller to provide these functions with
|
|
pre-allocated event structures.
|
|
.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 .
|
|
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 function
|
|
.Fn event_once
|
|
is similiar 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 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 0, 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
|
|
It is possible to disable support for
|
|
.Va epoll , kqueue , devpoll, poll ,
|
|
or
|
|
.Va select
|
|
by setting the environment variables
|
|
.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 EVENT PRIORITIES
|
|
By default
|
|
.Nm libevent
|
|
schedules all active events with the same priority.
|
|
However, sometime 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 ,
|
|
and
|
|
.Fn event_base_loopexit .
|
|
.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.
|
|
.Sh BUFFERED EVENTS
|
|
.Nm libevent
|
|
provides an abstraction on top of the regular event callbacks.
|
|
This abstraction is called a
|
|
.Dq Sy buffered event .
|
|
A buffered event provides input and output buffer 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 argument is specified by the fourth parameter
|
|
.Fa cbarg .
|
|
.Pp
|
|
By default the buffered event is read enabled and will try to read
|
|
from the file descriptor.
|
|
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.
|
|
The
|
|
.Fn bufferevent_read
|
|
function is used to read data from the input buffer.
|
|
Both functions return the amount of data written or read.
|
|
.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 select 2 ,
|
|
.Xr timeout 9
|
|
.Sh HISTORY
|
|
.Nm
|
|
appeared in
|
|
.Nx 2.0 .
|
|
The
|
|
.Nm event
|
|
API manpage is based on the
|
|
.Xr timeout 9
|
|
manpage by Artur Grabowski.
|
|
.Sh AUTHORS
|
|
The
|
|
.Nm event
|
|
library was written by Niels Provos.
|
|
.Sh BUGS
|
|
This documentation is neither complete nor authorative.
|
|
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.
|