|
|
|
.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14)
|
|
|
|
.\"
|
|
|
|
.\" Standard preamble:
|
|
|
|
.\" ========================================================================
|
|
|
|
.de Sp \" Vertical space (when we can't use .PP)
|
|
|
|
.if t .sp .5v
|
|
|
|
.if n .sp
|
|
|
|
..
|
|
|
|
.de Vb \" Begin verbatim text
|
|
|
|
.ft CW
|
|
|
|
.nf
|
|
|
|
.ne \\$1
|
|
|
|
..
|
|
|
|
.de Ve \" End verbatim text
|
|
|
|
.ft R
|
|
|
|
.fi
|
|
|
|
..
|
|
|
|
.\" Set up some character translations and predefined strings. \*(-- will
|
|
|
|
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
|
|
|
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
|
|
|
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
|
|
|
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
|
|
|
.\" nothing in troff, for use with C<>.
|
|
|
|
.tr \(*W-
|
|
|
|
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
|
|
|
.ie n \{\
|
|
|
|
. ds -- \(*W-
|
|
|
|
. ds PI pi
|
|
|
|
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
|
|
|
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
|
|
|
. ds L" ""
|
|
|
|
. ds R" ""
|
|
|
|
. ds C` ""
|
|
|
|
. ds C' ""
|
|
|
|
'br\}
|
|
|
|
.el\{\
|
|
|
|
. ds -- \|\(em\|
|
|
|
|
. ds PI \(*p
|
|
|
|
. ds L" ``
|
|
|
|
. ds R" ''
|
|
|
|
'br\}
|
|
|
|
.\"
|
|
|
|
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
|
|
|
.ie \n(.g .ds Aq \(aq
|
|
|
|
.el .ds Aq '
|
|
|
|
.\"
|
|
|
|
.\" If the F register is turned on, we'll generate index entries on stderr for
|
|
|
|
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
|
|
|
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
|
|
|
.\" output yourself in some meaningful fashion.
|
|
|
|
.ie \nF \{\
|
|
|
|
. de IX
|
|
|
|
. tm Index:\\$1\t\\n%\t"\\$2"
|
|
|
|
..
|
|
|
|
. nr % 0
|
|
|
|
. rr F
|
|
|
|
.\}
|
|
|
|
.el \{\
|
|
|
|
. de IX
|
|
|
|
..
|
|
|
|
.\}
|
|
|
|
.\"
|
|
|
|
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
|
|
|
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
|
|
|
. \" fudge factors for nroff and troff
|
|
|
|
.if n \{\
|
|
|
|
. ds #H 0
|
|
|
|
. ds #V .8m
|
|
|
|
. ds #F .3m
|
|
|
|
. ds #[ \f1
|
|
|
|
. ds #] \fP
|
|
|
|
.\}
|
|
|
|
.if t \{\
|
|
|
|
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
|
|
|
|
. ds #V .6m
|
|
|
|
. ds #F 0
|
|
|
|
. ds #[ \&
|
|
|
|
. ds #] \&
|
|
|
|
.\}
|
|
|
|
. \" simple accents for nroff and troff
|
|
|
|
.if n \{\
|
|
|
|
. ds ' \&
|
|
|
|
. ds ` \&
|
|
|
|
. ds ^ \&
|
|
|
|
. ds , \&
|
|
|
|
. ds ~ ~
|
|
|
|
. ds /
|
|
|
|
.\}
|
|
|
|
.if t \{\
|
|
|
|
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
|
|
|
|
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
|
|
|
|
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
|
|
|
|
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
|
|
|
|
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
|
|
|
|
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
|
|
|
|
.\}
|
|
|
|
. \" troff and (daisy-wheel) nroff accents
|
|
|
|
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
|
|
|
|
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
|
|
|
|
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
|
|
|
|
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
|
|
|
|
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
|
|
|
|
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
|
|
|
|
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
|
|
|
|
.ds ae a\h'-(\w'a'u*4/10)'e
|
|
|
|
.ds Ae A\h'-(\w'A'u*4/10)'E
|
|
|
|
. \" corrections for vroff
|
|
|
|
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
|
|
|
|
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
|
|
|
|
. \" for low resolution devices (crt and lpr)
|
|
|
|
.if \n(.H>23 .if \n(.V>19 \
|
|
|
|
\{\
|
|
|
|
. ds : e
|
|
|
|
. ds 8 ss
|
|
|
|
. ds o a
|
|
|
|
. ds d- d\h'-1'\(ga
|
|
|
|
. ds D- D\h'-1'\(hy
|
|
|
|
. ds th \o'bp'
|
|
|
|
. ds Th \o'LP'
|
|
|
|
. ds ae ae
|
|
|
|
. ds Ae AE
|
|
|
|
.\}
|
|
|
|
.rm #[ #] #H #V #F C
|
|
|
|
.\" ========================================================================
|
|
|
|
.\"
|
|
|
|
.IX Title "LIBEV 3"
|
|
|
|
.TH LIBEV 3 "2012-05-06" "libev-4.11" "libev - high performance full featured event loop"
|
|
|
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
|
|
|
.\" way too many mistakes in technical documents.
|
|
|
|
.if n .ad l
|
|
|
|
.nh
|
|
|
|
.SH "NAME"
|
|
|
|
libev \- a high performance full\-featured event loop written in C
|
|
|
|
.SH "SYNOPSIS"
|
|
|
|
.IX Header "SYNOPSIS"
|
|
|
|
.Vb 1
|
|
|
|
\& #include <ev.h>
|
|
|
|
.Ve
|
|
|
|
.SS "\s-1EXAMPLE\s0 \s-1PROGRAM\s0"
|
|
|
|
.IX Subsection "EXAMPLE PROGRAM"
|
|
|
|
.Vb 2
|
|
|
|
\& // a single header file is required
|
|
|
|
\& #include <ev.h>
|
|
|
|
\&
|
|
|
|
\& #include <stdio.h> // for puts
|
|
|
|
\&
|
|
|
|
\& // every watcher type has its own typedef\*(Aqd struct
|
|
|
|
\& // with the name ev_TYPE
|
|
|
|
\& ev_io stdin_watcher;
|
|
|
|
\& ev_timer timeout_watcher;
|
|
|
|
\&
|
|
|
|
\& // all watcher callbacks have a similar signature
|
|
|
|
\& // this callback is called when data is readable on stdin
|
|
|
|
\& static void
|
|
|
|
\& stdin_cb (EV_P_ ev_io *w, int revents)
|
|
|
|
\& {
|
|
|
|
\& puts ("stdin ready");
|
|
|
|
\& // for one\-shot events, one must manually stop the watcher
|
|
|
|
\& // with its corresponding stop function.
|
|
|
|
\& ev_io_stop (EV_A_ w);
|
|
|
|
\&
|
|
|
|
\& // this causes all nested ev_run\*(Aqs to stop iterating
|
|
|
|
\& ev_break (EV_A_ EVBREAK_ALL);
|
|
|
|
\& }
|
|
|
|
\&
|
|
|
|
\& // another callback, this time for a time\-out
|
|
|
|
\& static void
|
|
|
|
\& timeout_cb (EV_P_ ev_timer *w, int revents)
|
|
|
|
\& {
|
|
|
|
\& puts ("timeout");
|
|
|
|
\& // this causes the innermost ev_run to stop iterating
|
|
|
|
\& ev_break (EV_A_ EVBREAK_ONE);
|
|
|
|
\& }
|
|
|
|
\&
|
|
|
|
\& int
|
|
|
|
\& main (void)
|
|
|
|
\& {
|
|
|
|
\& // use the default event loop unless you have special needs
|
|
|
|
\& struct ev_loop *loop = EV_DEFAULT;
|
|
|
|
\&
|
|
|
|
\& // initialise an io watcher, then start it
|
|
|
|
\& // this one will watch for stdin to become readable
|
|
|
|
\& ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
|
|
|
|
\& ev_io_start (loop, &stdin_watcher);
|
|
|
|
\&
|
|
|
|
\& // initialise a timer watcher, then start it
|
|
|
|
\& // simple non\-repeating 5.5 second timeout
|
|
|
|
\& ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
|
|
|
|
\& ev_timer_start (loop, &timeout_watcher);
|
|
|
|
\&
|
|
|
|
\& // now wait for events to arrive
|
|
|
|
\& ev_run (loop, 0);
|
|
|
|
\&
|
|
|
|
\& // break was called, so exit
|
|
|
|
\& return 0;
|
|
|
|
\& }
|
|
|
|
.Ve
|
|
|
|
.SH "ABOUT THIS DOCUMENT"
|
|
|
|
.IX Header "ABOUT THIS DOCUMENT"
|
|
|
|
This document documents the libev software package.
|
|
|
|
.PP
|
|
|
|
The newest version of this document is also available as an html-formatted
|
|
|
|
web page you might find easier to navigate when reading it for the first
|
|
|
|
time: <http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod>.
|
|
|
|
.PP
|
|
|
|
While this document tries to be as complete as possible in documenting
|
|
|
|
libev, its usage and the rationale behind its design, it is not a tutorial
|
|
|
|
on event-based programming, nor will it introduce event-based programming
|
|
|
|
with libev.
|
|
|
|
.PP
|
|
|
|
Familiarity with event based programming techniques in general is assumed
|
|
|
|
throughout this document.
|
|
|
|
.SH "WHAT TO READ WHEN IN A HURRY"
|
|
|
|
.IX Header "WHAT TO READ WHEN IN A HURRY"
|
|
|
|
This manual tries to be very detailed, but unfortunately, this also makes
|
|
|
|
it very long. If you just want to know the basics of libev, I suggest
|
|
|
|
reading \*(L"\s-1ANATOMY\s0 \s-1OF\s0 A \s-1WATCHER\s0\*(R", then the \*(L"\s-1EXAMPLE\s0 \s-1PROGRAM\s0\*(R" above and
|
|
|
|
look up the missing functions in \*(L"\s-1GLOBAL\s0 \s-1FUNCTIONS\s0\*(R" and the \f(CW\*(C`ev_io\*(C'\fR and
|
|
|
|
\&\f(CW\*(C`ev_timer\*(C'\fR sections in \*(L"\s-1WATCHER\s0 \s-1TYPES\s0\*(R".
|
|
|
|
.SH "ABOUT LIBEV"
|
|
|
|
.IX Header "ABOUT LIBEV"
|
|
|
|
Libev is an event loop: you register interest in certain events (such as a
|
|
|
|
file descriptor being readable or a timeout occurring), and it will manage
|
|
|
|
these event sources and provide your program with events.
|
|
|
|
.PP
|
|
|
|
To do this, it must take more or less complete control over your process
|
|
|
|
(or thread) by executing the \fIevent loop\fR handler, and will then
|
|
|
|
communicate events via a callback mechanism.
|
|
|
|
.PP
|
|
|
|
You register interest in certain events by registering so-called \fIevent
|
|
|
|
watchers\fR, which are relatively small C structures you initialise with the
|
|
|
|
details of the event, and then hand it over to libev by \fIstarting\fR the
|
|
|
|
watcher.
|
|
|
|
.SS "\s-1FEATURES\s0"
|
|
|
|
.IX Subsection "FEATURES"
|
|
|
|
Libev supports \f(CW\*(C`select\*(C'\fR, \f(CW\*(C`poll\*(C'\fR, the Linux-specific \f(CW\*(C`epoll\*(C'\fR, the
|
|
|
|
BSD-specific \f(CW\*(C`kqueue\*(C'\fR and the Solaris-specific event port mechanisms
|
|
|
|
for file descriptor events (\f(CW\*(C`ev_io\*(C'\fR), the Linux \f(CW\*(C`inotify\*(C'\fR interface
|
|
|
|
(for \f(CW\*(C`ev_stat\*(C'\fR), Linux eventfd/signalfd (for faster and cleaner
|
|
|
|
inter-thread wakeup (\f(CW\*(C`ev_async\*(C'\fR)/signal handling (\f(CW\*(C`ev_signal\*(C'\fR)) relative
|
|
|
|
timers (\f(CW\*(C`ev_timer\*(C'\fR), absolute timers with customised rescheduling
|
|
|
|
(\f(CW\*(C`ev_periodic\*(C'\fR), synchronous signals (\f(CW\*(C`ev_signal\*(C'\fR), process status
|
|
|
|
change events (\f(CW\*(C`ev_child\*(C'\fR), and event watchers dealing with the event
|
|
|
|
loop mechanism itself (\f(CW\*(C`ev_idle\*(C'\fR, \f(CW\*(C`ev_embed\*(C'\fR, \f(CW\*(C`ev_prepare\*(C'\fR and
|
|
|
|
\&\f(CW\*(C`ev_check\*(C'\fR watchers) as well as file watchers (\f(CW\*(C`ev_stat\*(C'\fR) and even
|
|
|
|
limited support for fork events (\f(CW\*(C`ev_fork\*(C'\fR).
|
|
|
|
.PP
|
|
|
|
It also is quite fast (see this
|
|
|
|
benchmark <http://libev.schmorp.de/bench.html> comparing it to libevent
|
|
|
|
for example).
|
|
|
|
.SS "\s-1CONVENTIONS\s0"
|
|
|
|
.IX Subsection "CONVENTIONS"
|
|
|
|
Libev is very configurable. In this manual the default (and most common)
|
|
|
|
configuration will be described, which supports multiple event loops. For
|
|
|
|
more info about various configuration options please have a look at
|
|
|
|
\&\fB\s-1EMBED\s0\fR section in this manual. If libev was configured without support
|
|
|
|
for multiple event loops, then all functions taking an initial argument of
|
|
|
|
name \f(CW\*(C`loop\*(C'\fR (which is always of type \f(CW\*(C`struct ev_loop *\*(C'\fR) will not have
|
|
|
|
this argument.
|
|
|
|
.SS "\s-1TIME\s0 \s-1REPRESENTATION\s0"
|
|
|
|
.IX Subsection "TIME REPRESENTATION"
|
|
|
|
Libev represents time as a single floating point number, representing
|
|
|
|
the (fractional) number of seconds since the (\s-1POSIX\s0) epoch (in practice
|
|
|
|
somewhere near the beginning of 1970, details are complicated, don't
|
|
|
|
ask). This type is called \f(CW\*(C`ev_tstamp\*(C'\fR, which is what you should use
|
|
|
|
too. It usually aliases to the \f(CW\*(C`double\*(C'\fR type in C. When you need to do
|
|
|
|
any calculations on it, you should treat it as some floating point value.
|
|
|
|
.PP
|
|
|
|
Unlike the name component \f(CW\*(C`stamp\*(C'\fR might indicate, it is also used for
|
|
|
|
time differences (e.g. delays) throughout libev.
|
|
|
|
.SH "ERROR HANDLING"
|
|
|
|
.IX Header "ERROR HANDLING"
|
|
|
|
Libev knows three classes of errors: operating system errors, usage errors
|
|
|
|
and internal errors (bugs).
|
|
|
|
.PP
|
|
|
|
When libev catches an operating system error it cannot handle (for example
|
|
|
|
a system call indicating a condition libev cannot fix), it calls the callback
|
|
|
|
set via \f(CW\*(C`ev_set_syserr_cb\*(C'\fR, which is supposed to fix the problem or
|
|
|
|
abort. The default is to print a diagnostic message and to call \f(CW\*(C`abort
|
|
|
|
()\*(C'\fR.
|
|
|
|
.PP
|
|
|
|
When libev detects a usage error such as a negative timer interval, then
|
|
|
|
it will print a diagnostic message and abort (via the \f(CW\*(C`assert\*(C'\fR mechanism,
|
|
|
|
so \f(CW\*(C`NDEBUG\*(C'\fR will disable this checking): these are programming errors in
|
|
|
|
the libev caller and need to be fixed there.
|
|
|
|
.PP
|
|
|
|
Libev also has a few internal error-checking \f(CW\*(C`assert\*(C'\fRions, and also has
|
|
|
|
extensive consistency checking code. These do not trigger under normal
|
|
|
|
circumstances, as they indicate either a bug in libev or worse.
|
|
|
|
.SH "GLOBAL FUNCTIONS"
|
|
|
|
.IX Header "GLOBAL FUNCTIONS"
|
|
|
|
These functions can be called anytime, even before initialising the
|
|
|
|
library in any way.
|
|
|
|
.IP "ev_tstamp ev_time ()" 4
|
|
|
|
.IX Item "ev_tstamp ev_time ()"
|
|
|
|
Returns the current time as libev would use it. Please note that the
|
|
|
|
\&\f(CW\*(C`ev_now\*(C'\fR function is usually faster and also often returns the timestamp
|
|
|
|
you actually want to know. Also interesting is the combination of
|
|
|
|
\&\f(CW\*(C`ev_now_update\*(C'\fR and \f(CW\*(C`ev_now\*(C'\fR.
|
|
|
|
.IP "ev_sleep (ev_tstamp interval)" 4
|
|
|
|
.IX Item "ev_sleep (ev_tstamp interval)"
|
|
|
|
Sleep for the given interval: The current thread will be blocked
|
|
|
|
until either it is interrupted or the given time interval has
|
|
|
|
passed (approximately \- it might return a bit earlier even if not
|
|
|
|
interrupted). Returns immediately if \f(CW\*(C`interval <= 0\*(C'\fR.
|
|
|
|
.Sp
|
|
|
|
Basically this is a sub-second-resolution \f(CW\*(C`sleep ()\*(C'\fR.
|
|
|
|
.Sp
|
|
|
|
The range of the \f(CW\*(C`interval\*(C'\fR is limited \- libev only guarantees to work
|
|
|
|
with sleep times of up to one day (\f(CW\*(C`interval <= 86400\*(C'\fR).
|
|
|
|
.IP "int ev_version_major ()" 4
|
|
|
|
.IX Item "int ev_version_major ()"
|
|
|
|
.PD 0
|
|
|
|
.IP "int ev_version_minor ()" 4
|
|
|
|
.IX Item "int ev_version_minor ()"
|
|
|
|
.PD
|
|
|
|
You can find out the major and minor \s-1ABI\s0 version numbers of the library
|
|
|
|
you linked against by calling the functions \f(CW\*(C`ev_version_major\*(C'\fR and
|
|
|
|
\&\f(CW\*(C`ev_version_minor\*(C'\fR. If you want, you can compare against the global
|
|
|
|
symbols \f(CW\*(C`EV_VERSION_MAJOR\*(C'\fR and \f(CW\*(C`EV_VERSION_MINOR\*(C'\fR, which specify the
|
|
|
|
version of the library your program was compiled against.
|
|
|
|
.Sp
|
|
|
|
These version numbers refer to the \s-1ABI\s0 version of the library, not the
|
|
|
|
release version.
|
|
|
|
.Sp
|
|
|
|
Usually, it's a good idea to terminate if the major versions mismatch,
|
|
|
|
as this indicates an incompatible change. Minor versions are usually
|
|
|
|
compatible to older versions, so a larger minor version alone is usually
|
|
|
|
not a problem.
|
|
|
|
.Sp
|
|
|
|
Example: Make sure we haven't accidentally been linked against the wrong
|
|
|
|
version (note, however, that this will not detect other \s-1ABI\s0 mismatches,
|
|
|
|
such as \s-1LFS\s0 or reentrancy).
|
|
|
|
.Sp
|
|
|
|
.Vb 3
|
|
|
|
\& assert (("libev version mismatch",
|
|
|
|
\& ev_version_major () == EV_VERSION_MAJOR
|
|
|
|
\& && ev_version_minor () >= EV_VERSION_MINOR));
|
|
|
|
.Ve
|
|
|
|
.IP "unsigned int ev_supported_backends ()" 4
|
|
|
|
.IX Item "unsigned int ev_supported_backends ()"
|
|
|
|
Return the set of all backends (i.e. their corresponding \f(CW\*(C`EV_BACKEND_*\*(C'\fR
|
|
|
|
value) compiled into this binary of libev (independent of their
|
|
|
|
availability on the system you are running on). See \f(CW\*(C`ev_default_loop\*(C'\fR for
|
|
|
|
a description of the set values.
|
|
|
|
.Sp
|
|
|
|
Example: make sure we have the epoll method, because yeah this is cool and
|
|
|
|
a must have and can we have a torrent of it please!!!11
|
|
|
|
.Sp
|
|
|
|
.Vb 2
|
|
|
|
\& assert (("sorry, no epoll, no sex",
|
|
|
|
\& ev_supported_backends () & EVBACKEND_EPOLL));
|
|
|
|
.Ve
|
|
|
|
.IP "unsigned int ev_recommended_backends ()" 4
|
|
|
|
.IX Item "unsigned int ev_recommended_backends ()"
|
|
|
|
Return the set of all backends compiled into this binary of libev and
|
|
|
|
also recommended for this platform, meaning it will work for most file
|
|
|
|
descriptor types. This set is often smaller than the one returned by
|
|
|
|
\&\f(CW\*(C`ev_supported_backends\*(C'\fR, as for example kqueue is broken on most BSDs
|
|
|
|
and will not be auto-detected unless you explicitly request it (assuming
|
|
|
|
you know what you are doing). This is the set of backends that libev will
|
|
|
|
probe for if you specify no backends explicitly.
|
|
|
|
.IP "unsigned int ev_embeddable_backends ()" 4
|
|
|
|
.IX Item "unsigned int ev_embeddable_backends ()"
|
|
|
|
Returns the set of backends that are embeddable in other event loops. This
|
|
|
|
value is platform-specific but can include backends not available on the
|
|
|
|
current system. To find which embeddable backends might be supported on
|
|
|
|
the current system, you would need to look at \f(CW\*(C`ev_embeddable_backends ()
|
|
|
|
& ev_supported_backends ()\*(C'\fR, likewise for recommended ones.
|
|
|
|
.Sp
|
|
|
|
See the description of \f(CW\*(C`ev_embed\*(C'\fR watchers for more info.
|
|
|
|
.IP "ev_set_allocator (void *(*cb)(void *ptr, long size) throw ())" 4
|
|
|
|
.IX Item "ev_set_allocator (void *(*cb)(void *ptr, long size) throw ())"
|
|
|
|
Sets the allocation function to use (the prototype is similar \- the
|
|
|
|
semantics are identical to the \f(CW\*(C`realloc\*(C'\fR C89/SuS/POSIX function). It is
|
|
|
|
used to allocate and free memory (no surprises here). If it returns zero
|
|
|
|
when memory needs to be allocated (\f(CW\*(C`size != 0\*(C'\fR), the library might abort
|
|
|
|
or take some potentially destructive action.
|
|
|
|
.Sp
|
|
|
|
Since some systems (at least OpenBSD and Darwin) fail to implement
|
|
|
|
correct \f(CW\*(C`realloc\*(C'\fR semantics, libev will use a wrapper around the system
|
|
|
|
\&\f(CW\*(C`realloc\*(C'\fR and \f(CW\*(C`free\*(C'\fR functions by default.
|
|
|
|
.Sp
|
|
|
|
You could override this function in high-availability programs to, say,
|
|
|
|
free some memory if it cannot allocate memory, to use a special allocator,
|
|
|
|
or even to sleep a while and retry until some memory is available.
|
|
|
|
.Sp
|
|
|
|
Example: Replace the libev allocator with one that waits a bit and then
|
|
|
|
retries (example requires a standards-compliant \f(CW\*(C`realloc\*(C'\fR).
|
|
|
|
.Sp
|
|
|
|
.Vb 6
|
|
|
|
\& static void *
|
|
|
|
\& persistent_realloc (void *ptr, size_t size)
|
|
|
|
\& {
|
|
|
|
\& for (;;)
|
|
|
|
\& {
|
|
|
|
\& void *newptr = realloc (ptr, size);
|
|
|
|
\&
|
|
|
|
\& if (newptr)
|
|
|
|
\& return newptr;
|
|
|
|
\&
|
|
|
|
\& sleep (60);
|
|
|
|
\& }
|
|
|
|
\& }
|
|
|
|
\&
|
|
|
|
\& ...
|
|
|
|
\& ev_set_allocator (persistent_realloc);
|
|
|
|
.Ve
|
|
|
|
.IP "ev_set_syserr_cb (void (*cb)(const char *msg) throw ())" 4
|
|
|
|
.IX Item "ev_set_syserr_cb (void (*cb)(const char *msg) throw ())"
|
|
|
|
Set the callback function to call on a retryable system call error (such
|
|
|
|
as failed select, poll, epoll_wait). The message is a printable string
|
|
|
|
indicating the system call or subsystem causing the problem. If this
|
|
|
|
callback is set, then libev will expect it to remedy the situation, no
|
|
|
|
matter what, when it returns. That is, libev will generally retry the
|
|
|
|
requested operation, or, if the condition doesn't go away, do bad stuff
|
|
|
|
(such as abort).
|
|
|
|
.Sp
|
|
|
|
Example: This is basically the same thing that libev does internally, too.
|
|
|
|
.Sp
|
|
|
|
.Vb 6
|
|
|
|
\& static void
|
|
|
|
\& fatal_error (const char *msg)
|
|
|
|
\& {
|
|
|
|
\& perror (msg);
|
|
|
|
\& abort ();
|
|
|
|
\& }
|
|
|
|
\&
|
|
|
|
\& ...
|
|
|
|
\& ev_set_syserr_cb (fatal_error);
|
|
|
|
.Ve
|
|
|
|
.IP "ev_feed_signal (int signum)" 4
|
|
|
|
.IX Item "ev_feed_signal (int signum)"
|
|
|
|
This function can be used to \*(L"simulate\*(R" a signal receive. It is completely
|
|
|
|
safe to call this function at any time, from any context, including signal
|
|
|
|
handlers or random threads.
|
|
|
|
.Sp
|
|
|
|
Its main use is to customise signal handling in your process, especially
|
|
|
|
in the presence of threads. For example, you could block signals
|
|
|
|
by default in all threads (and specifying \f(CW\*(C`EVFLAG_NOSIGMASK\*(C'\fR when
|
|
|
|
creating any loops), and in one thread, use \f(CW\*(C`sigwait\*(C'\fR or any other
|
|
|
|
mechanism to wait for signals, then \*(L"deliver\*(R" them to libev by calling
|
|
|
|
\&\f(CW\*(C`ev_feed_signal\*(C'\fR.
|
|
|
|
.SH "FUNCTIONS CONTROLLING EVENT LOOPS"
|
|
|
|
.IX Header "FUNCTIONS CONTROLLING EVENT LOOPS"
|
|
|
|
An event loop is described by a \f(CW\*(C`struct ev_loop *\*(C'\fR (the \f(CW\*(C`struct\*(C'\fR is
|
|
|
|
\&\fInot\fR optional in this case unless libev 3 compatibility is disabled, as
|
|
|
|
libev 3 had an \f(CW\*(C`ev_loop\*(C'\fR function colliding with the struct name).
|
|
|
|
.PP
|
|
|
|
The library knows two types of such loops, the \fIdefault\fR loop, which
|
|
|
|
supports child process events, and dynamically created event loops which
|
|
|
|
do not.
|
|
|
|
.IP "struct ev_loop *ev_default_loop (unsigned int flags)" 4
|
|
|
|
.IX Item "struct ev_loop *ev_default_loop (unsigned int flags)"
|
|
|
|
This returns the \*(L"default\*(R" event loop object, which is what you should
|
|
|
|
normally use when you just need \*(L"the event loop\*(R". Event loop objects and
|
|
|
|
the \f(CW\*(C`flags\*(C'\fR parameter are described in more detail in the entry for
|
|
|
|
\&\f(CW\*(C`ev_loop_new\*(C'\fR.
|
|
|
|
.Sp
|
|
|
|
If the default loop is already initialised then this function simply
|
|
|
|
returns it (and ignores the flags. If that is troubling you, check
|
|
|
|
\&\f(CW\*(C`ev_backend ()\*(C'\fR afterwards). Otherwise it will create it with the given
|
|
|
|
flags, which should almost always be \f(CW0\fR, unless the caller is also the
|
|
|
|
one calling \f(CW\*(C`ev_run\*(C'\fR or otherwise qualifies as \*(L"the main program\*(R".
|
|
|
|
.Sp
|
|
|
|
If you don't know what event loop to use, use the one returned from this
|
|
|
|
function (or via the \f(CW\*(C`EV_DEFAULT\*(C'\fR macro).
|
|
|
|
.Sp
|
|
|
|
Note that this function is \fInot\fR thread-safe, so if you want to use it
|
|
|
|
from multiple threads, you have to employ some kind of mutex (note also
|
|
|
|
that this case is unlikely, as loops cannot be shared easily between
|
|
|
|
threads anyway).
|
|
|
|
.Sp
|
|
|
|
The default loop is the only loop that can handle \f(CW\*(C`ev_child\*(C'\fR watchers,
|
|
|
|
and to do this, it always registers a handler for \f(CW\*(C`SIGCHLD\*(C'\fR. If this is
|
|
|
|
a problem for your application you can either create a dynamic loop with
|
|
|
|
\&\f(CW\*(C`ev_loop_new\*(C'\fR which doesn't do that, or you can simply overwrite the
|
|
|
|
\&\f(CW\*(C`SIGCHLD\*(C'\fR signal handler \fIafter\fR calling \f(CW\*(C`ev_default_init\*(C'\fR.
|
|
|
|
.Sp
|
|
|
|
Example: This is the most typical usage.
|
|
|
|
.Sp
|
|
|
|
.Vb 2
|
|
|
|
\& if (!ev_default_loop (0))
|
|
|
|
\& fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?");
|
|
|
|
.Ve
|
|
|
|
.Sp
|
|
|
|
Example: Restrict libev to the select and poll backends, and do not allow
|
|
|
|
environment settings to be taken into account:
|
|
|
|
.Sp
|
|
|
|
.Vb 1
|
|
|
|
\& ev_default_loop (EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV);
|
|
|
|
.Ve
|
|
|
|
.IP "struct ev_loop *ev_loop_new (unsigned int flags)" 4
|
|
|
|
.IX Item "struct ev_loop *ev_loop_new (unsigned int flags)"
|
|
|
|
This will create and initialise a new event loop object. If the loop
|
|
|
|
could not be initialised, returns false.
|
|
|
|
.Sp
|
|
|
|
This function is thread-safe, and one common way to use libev with
|
|
|
|
threads is indeed to create one loop per thread, and using the default
|
|
|
|
loop in the \*(L"main\*(R" or \*(L"initial\*(R" thread.
|
|
|
|
.Sp
|
|
|
|
The flags argument can be used to specify special behaviour or specific
|
|
|
|
backends to use, and is usually specified as \f(CW0\fR (or \f(CW\*(C`EVFLAG_AUTO\*(C'\fR).
|
|
|
|
.Sp
|
|
|
|
The following flags are supported:
|
|
|
|
.RS 4
|
|
|
|
.ie n .IP """EVFLAG_AUTO""" 4
|
|
|
|
.el .IP "\f(CWEVFLAG_AUTO\fR" 4
|
|
|
|
.IX Item "EVFLAG_AUTO"
|
|
|
|
The default flags value. Use this if you have no clue (it's the right
|
|
|
|
thing, believe me).
|
|
|
|
.ie n .IP """EVFLAG_NOENV""" 4
|
|
|
|
.el .IP "\f(CWEVFLAG_NOENV\fR" 4
|
|
|
|
.IX Item "EVFLAG_NOENV"
|
|
|
|
If this flag bit is or'ed into the flag value (or the program runs setuid
|
|
|
|
or setgid) then libev will \fInot\fR look at the environment variable
|
|
|
|
\&\f(CW\*(C`LIBEV_FLAGS\*(C'\fR. Otherwise (the default), this environment variable will
|
|
|
|
override the flags completely if it is found in the environment. This is
|
|
|
|
useful to try out specific backends to test their performance, or to work
|
|
|
|
around bugs.
|
|
|
|
.ie n .IP """EVFLAG_FORKCHECK""" 4
|
|
|
|
.el .IP "\f(CWEVFLAG_FORKCHECK\fR" 4
|
|
|
|
.IX Item "EVFLAG_FORKCHECK"
|
|
|
|
Instead of calling \f(CW\*(C`ev_loop_fork\*(C'\fR manually after a fork, you can also
|
|
|
|
make libev check for a fork in each iteration by enabling this flag.
|
|
|
|
.Sp
|
|
|
|
This works by calling \f(CW\*(C`getpid ()\*(C'\fR on every iteration of the loop,
|
|
|
|
and thus this might slow down your event loop if you do a lot of loop
|
|
|
|
iterations and little real work, but is usually not noticeable (on my
|
|
|
|
GNU/Linux system for example, \f(CW\*(C`getpid\*(C'\fR is actually a simple 5\-insn sequence
|
|
|
|
without a system call and thus \fIvery\fR fast, but my GNU/Linux system also has
|
|
|
|
\&\f(CW\*(C`pthread_atfork\*(C'\fR which is even faster).
|
|
|
|
.Sp
|
|
|
|
The big advantage of this flag is that you can forget about fork (and
|
|
|
|
forget about forgetting to tell libev about forking) when you use this
|
|
|
|
flag.
|
|
|
|
.Sp
|
|
|
|
This flag setting cannot be overridden or specified in the \f(CW\*(C`LIBEV_FLAGS\*(C'\fR
|
|
|
|
environment variable.
|
|
|
|
.ie n .IP """EVFLAG_NOINOTIFY""" 4
|
|
|
|
.el .IP "\f(CWEVFLAG_NOINOTIFY\fR" 4
|
|
|
|
.IX Item "EVFLAG_NOINOTIFY"
|
|
|
|
When this flag is specified, then libev will not attempt to use the
|
|
|
|
\&\fIinotify\fR \s-1API\s0 for its \f(CW\*(C`ev_stat\*(C'\fR watchers. Apart from debugging and
|
|
|
|
testing, this flag can be useful to conserve inotify file descriptors, as
|
|
|
|
otherwise each loop using \f(CW\*(C`ev_stat\*(C'\fR watchers consumes one inotify handle.
|
|
|
|
.ie n .IP """EVFLAG_SIGNALFD""" 4
|
|
|
|
.el .IP "\f(CWEVFLAG_SIGNALFD\fR" 4
|
|
|
|
.IX Item "EVFLAG_SIGNALFD"
|
|
|
|
When this flag is specified, then libev will attempt to use the
|
|
|
|
\&\fIsignalfd\fR \s-1API\s0 for its \f(CW\*(C`ev_signal\*(C'\fR (and \f(CW\*(C`ev_child\*(C'\fR) watchers. This \s-1API\s0
|
|
|
|
delivers signals synchronously, which makes it both faster and might make
|
|
|
|
it possible to get the queued signal data. It can also simplify signal
|
|
|
|
handling with threads, as long as you properly block signals in your
|
|
|
|
threads that are not interested in handling them.
|
|
|
|
.Sp
|
|
|
|
Signalfd will not be used by default as this changes your signal mask, and
|
|
|
|
there are a lot of shoddy libraries and programs (glib's threadpool for
|
|
|
|
example) that can't properly initialise their signal masks.
|
|
|
|
.ie n .IP """EVFLAG_NOSIGMASK""" 4
|
|
|
|
.el .IP "\f(CWEVFLAG_NOSIGMASK\fR" 4
|
|
|
|
.IX Item "EVFLAG_NOSIGMASK"
|
|
|
|
When this flag is specified, then libev will avoid to modify the signal
|
|
|
|
mask. Specifically, this means you have to make sure signals are unblocked
|
|
|
|
when you want to receive them.
|
|
|
|
.Sp
|
|
|
|
This behaviour is useful when you want to do your own signal handling, or
|
|
|
|
want to handle signals only in specific threads and want to avoid libev
|
|
|
|
unblocking the signals.
|
|
|
|
.Sp
|
|
|
|
It's also required by \s-1POSIX\s0 in a threaded program, as libev calls
|
|
|
|
\&\f(CW\*(C`sigprocmask\*(C'\fR, whose behaviour is officially unspecified.
|
|
|
|
.Sp
|
|
|
|
This flag's behaviour will become the default in future versions of libev.
|
|
|
|
.ie n .IP """EVBACKEND_SELECT"" (value 1, portable select backend)" 4
|
|
|
|
.el .IP "\f(CWEVBACKEND_SELECT\fR (value 1, portable select backend)" 4
|
|
|
|
.IX Item "EVBACKEND_SELECT (value 1, portable select backend)"
|
|
|
|
This is your standard \fIselect\fR\|(2) backend. Not \fIcompletely\fR standard, as
|
|
|
|
libev tries to roll its own fd_set with no limits on the number of fds,
|
|
|
|
but if that fails, expect a fairly low limit on the number of fds when
|
|
|
|
using this backend. It doesn't scale too well (O(highest_fd)), but its
|
|
|
|
usually the fastest backend for a low number of (low-numbered :) fds.
|
|
|
|
.Sp
|
|
|
|
To get good performance out of this backend you need a high amount of
|
|
|
|
parallelism (most of the file descriptors should be busy). If you are
|
|
|
|
writing a server, you should \f(CW\*(C`accept ()\*(C'\fR in a loop to accept as many
|
|
|
|
connections as possible during one iteration. You might also want to have
|
|
|
|
a look at \f(CW\*(C`ev_set_io_collect_interval ()\*(C'\fR to increase the amount of
|
|
|
|
readiness notifications you get per iteration.
|
|
|
|
.Sp
|
|
|
|
This backend maps \f(CW\*(C`EV_READ\*(C'\fR to the \f(CW\*(C`readfds\*(C'\fR set and \f(CW\*(C`EV_WRITE\*(C'\fR to the
|
|
|
|
\&\f(CW\*(C`writefds\*(C'\fR set (and to work around Microsoft Windows bugs, also onto the
|
|
|
|
\&\f(CW\*(C`exceptfds\*(C'\fR set on that platform).
|
|
|
|
.ie n .IP """EVBACKEND_POLL"" (value 2, poll backend, available everywhere except on windows)" 4
|
|
|
|
.el .IP "\f(CWEVBACKEND_POLL\fR (value 2, poll backend, available everywhere except on windows)" 4
|
|
|
|
.IX Item "EVBACKEND_POLL (value 2, poll backend, available everywhere except on windows)"
|
|
|
|
And this is your standard \fIpoll\fR\|(2) backend. It's more complicated
|
|
|
|
than select, but handles sparse fds better and has no artificial
|
|
|
|
limit on the number of fds you can use (except it will slow down
|
|
|
|
considerably with a lot of inactive fds). It scales similarly to select,
|
|
|
|
i.e. O(total_fds). See the entry for \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR, above, for
|
|
|
|
performance tips.
|
|
|
|
.Sp
|
|
|
|
This backend maps \f(CW\*(C`EV_READ\*(C'\fR to \f(CW\*(C`POLLIN | POLLERR | POLLHUP\*(C'\fR, and
|
|
|
|
\&\f(CW\*(C`EV_WRITE\*(C'\fR to \f(CW\*(C`POLLOUT | POLLERR | POLLHUP\*(C'\fR.
|
|
|
|
.ie n .IP """EVBACKEND_EPOLL"" (value 4, Linux)" 4
|
|
|
|
.el .IP "\f(CWEVBACKEND_EPOLL\fR (value 4, Linux)" 4
|
|
|
|
.IX Item "EVBACKEND_EPOLL (value 4, Linux)"
|
|
|
|
Use the linux-specific \fIepoll\fR\|(7) interface (for both pre\- and post\-2.6.9
|
|
|
|
kernels).
|
|
|
|
.Sp
|
|
|
|
For few fds, this backend is a bit little slower than poll and select, but
|
|
|
|
it scales phenomenally better. While poll and select usually scale like
|
|
|
|
O(total_fds) where total_fds is the total number of fds (or the highest
|
|
|
|
fd), epoll scales either O(1) or O(active_fds).
|
|
|
|
.Sp
|
|
|
|
The epoll mechanism deserves honorable mention as the most misdesigned
|
|
|
|
of the more advanced event mechanisms: mere annoyances include silently
|
|
|
|
dropping file descriptors, requiring a system call per change per file
|
|
|
|
descriptor (and unnecessary guessing of parameters), problems with dup,
|
|
|
|
returning before the timeout value, resulting in additional iterations
|
|
|
|
(and only giving 5ms accuracy while select on the same platform gives
|
|
|
|
0.1ms) and so on. The biggest issue is fork races, however \- if a program
|
|
|
|
forks then \fIboth\fR parent and child process have to recreate the epoll
|
|
|
|
set, which can take considerable time (one syscall per file descriptor)
|
|
|
|
and is of course hard to detect.
|
|
|
|
.Sp
|
|
|
|
Epoll is also notoriously buggy \- embedding epoll fds \fIshould\fR work,
|
|
|
|
but of course \fIdoesn't\fR, and epoll just loves to report events for
|
|
|
|
totally \fIdifferent\fR file descriptors (even already closed ones, so
|
|
|
|
one cannot even remove them from the set) than registered in the set
|
|
|
|
(especially on \s-1SMP\s0 systems). Libev tries to counter these spurious
|
|
|
|
notifications by employing an additional generation counter and comparing
|
|
|
|
that against the events to filter out spurious ones, recreating the set
|
|
|
|
when required. Epoll also erroneously rounds down timeouts, but gives you
|
|
|
|
no way to know when and by how much, so sometimes you have to busy-wait
|
|
|
|
because epoll returns immediately despite a nonzero timeout. And last
|
|
|
|
not least, it also refuses to work with some file descriptors which work
|
|
|
|
perfectly fine with \f(CW\*(C`select\*(C'\fR (files, many character devices...).
|
|
|
|
.Sp
|
|
|
|
Epoll is truly the train wreck among event poll mechanisms, a frankenpoll,
|
|
|
|
cobbled together in a hurry, no thought to design or interaction with
|
|
|
|
others. Oh, the pain, will it ever stop...
|
|
|
|
.Sp
|
|
|
|
While stopping, setting and starting an I/O watcher in the same iteration
|
|
|
|
will result in some caching, there is still a system call per such
|
|
|
|
incident (because the same \fIfile descriptor\fR could point to a different
|
|
|
|
\&\fIfile description\fR now), so its best to avoid that. Also, \f(CW\*(C`dup ()\*(C'\fR'ed
|
|
|
|
file descriptors might not work very well if you register events for both
|
|
|
|
file descriptors.
|
|
|
|
.Sp
|
|
|
|
Best performance from this backend is achieved by not unregistering all
|
|
|
|
watchers for a file descriptor until it has been closed, if possible,
|
|
|
|
i.e. keep at least one watcher active per fd at all times. Stopping and
|
|
|
|
starting a watcher (without re-setting it) also usually doesn't cause
|
|
|
|
extra overhead. A fork can both result in spurious notifications as well
|
|
|
|
as in libev having to destroy and recreate the epoll object, which can
|
|
|
|
take considerable time and thus should be avoided.
|
|
|
|
.Sp
|
|
|
|
All this means that, in practice, \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR can be as fast or
|
|
|
|
faster than epoll for maybe up to a hundred file descriptors, depending on
|
|
|
|
the usage. So sad.
|
|
|
|
.Sp
|
|
|
|
While nominally embeddable in other event loops, this feature is broken in
|
|
|
|
all kernel versions tested so far.
|
|
|
|
.Sp
|
|
|
|
This backend maps \f(CW\*(C`EV_READ\*(C'\fR and \f(CW\*(C`EV_WRITE\*(C'\fR in the same way as
|
|
|
|
\&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
|
|
|
|
.ie n .IP """EVBACKEND_KQUEUE"" (value 8, most \s-1BSD\s0 clones)" 4
|
|
|
|
.el .IP "\f(CWEVBACKEND_KQUEUE\fR (value 8, most \s-1BSD\s0 clones)" 4
|
|
|
|
.IX Item "EVBACKEND_KQUEUE (value 8, most BSD clones)"
|
|
|
|
Kqueue deserves special mention, as at the time of this writing, it
|
|
|
|
was broken on all BSDs except NetBSD (usually it doesn't work reliably
|
|
|
|
with anything but sockets and pipes, except on Darwin, where of course
|
|
|
|
it's completely useless). Unlike epoll, however, whose brokenness
|
|
|
|
is by design, these kqueue bugs can (and eventually will) be fixed
|
|
|
|
without \s-1API\s0 changes to existing programs. For this reason it's not being
|
|
|
|
\&\*(L"auto-detected\*(R" unless you explicitly specify it in the flags (i.e. using
|
|
|
|
\&\f(CW\*(C`EVBACKEND_KQUEUE\*(C'\fR) or libev was compiled on a known-to-be-good (\-enough)
|
|
|
|
system like NetBSD.
|
|
|
|
.Sp
|
|
|
|
You still can embed kqueue into a normal poll or select backend and use it
|
|
|
|
only for sockets (after having made sure that sockets work with kqueue on
|
|
|
|
the target platform). See \f(CW\*(C`ev_embed\*(C'\fR watchers for more info.
|
|
|
|
.Sp
|
|
|
|
It scales in the same way as the epoll backend, but the interface to the
|
|
|
|
kernel is more efficient (which says nothing about its actual speed, of
|
|
|
|
course). While stopping, setting and starting an I/O watcher does never
|
|
|
|
cause an extra system call as with \f(CW\*(C`EVBACKEND_EPOLL\*(C'\fR, it still adds up to
|
|
|
|
two event changes per incident. Support for \f(CW\*(C`fork ()\*(C'\fR is very bad (you
|
|
|
|
might have to leak fd's on fork, but it's more sane than epoll) and it
|
|
|
|
drops fds silently in similarly hard-to-detect cases
|
|
|
|
.Sp
|
|
|
|
This backend usually performs well under most conditions.
|
|
|
|
.Sp
|
|
|
|
While nominally embeddable in other event loops, this doesn't work
|
|
|
|
everywhere, so you might need to test for this. And since it is broken
|
|
|
|
almost everywhere, you should only use it when you have a lot of sockets
|
|
|
|
(for which it usually works), by embedding it into another event loop
|
|
|
|
(e.g. \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR (but \f(CW\*(C`poll\*(C'\fR is of course
|
|
|
|
also broken on \s-1OS\s0 X)) and, did I mention it, using it only for sockets.
|
|
|
|
.Sp
|
|
|
|
This backend maps \f(CW\*(C`EV_READ\*(C'\fR into an \f(CW\*(C`EVFILT_READ\*(C'\fR kevent with
|
|
|
|
\&\f(CW\*(C`NOTE_EOF\*(C'\fR, and \f(CW\*(C`EV_WRITE\*(C'\fR into an \f(CW\*(C`EVFILT_WRITE\*(C'\fR kevent with
|
|
|
|
\&\f(CW\*(C`NOTE_EOF\*(C'\fR.
|
|
|
|
.ie n .IP """EVBACKEND_DEVPOLL"" (value 16, Solaris 8)" 4
|
|
|
|
.el .IP "\f(CWEVBACKEND_DEVPOLL\fR (value 16, Solaris 8)" 4
|
|
|
|
.IX Item "EVBACKEND_DEVPOLL (value 16, Solaris 8)"
|
|
|
|
This is not implemented yet (and might never be, unless you send me an
|
|
|
|
implementation). According to reports, \f(CW\*(C`/dev/poll\*(C'\fR only supports sockets
|
|
|
|
and is not embeddable, which would limit the usefulness of this backend
|
|
|
|
immensely.
|
|
|
|
.ie n .IP """EVBACKEND_PORT"" (value 32, Solaris 10)" 4
|
|
|
|
.el .IP "\f(CWEVBACKEND_PORT\fR (value 32, Solaris 10)" 4
|
|
|
|
.IX Item "EVBACKEND_PORT (value 32, Solaris 10)"
|
|
|
|
This uses the Solaris 10 event port mechanism. As with everything on Solaris,
|
|
|
|
it's really slow, but it still scales very well (O(active_fds)).
|
|
|
|
.Sp
|
|
|
|
While this backend scales well, it requires one system call per active
|
|
|
|
file descriptor per loop iteration. For small and medium numbers of file
|
|
|
|
descriptors a \*(L"slow\*(R" \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR backend
|
|
|
|
might perform better.
|
|
|
|
.Sp
|
|
|
|
On the positive side, this backend actually performed fully to
|
|
|
|
specification in all tests and is fully embeddable, which is a rare feat
|
|
|
|
among the OS-specific backends (I vastly prefer correctness over speed
|
|
|
|
hacks).
|
|
|
|
.Sp
|
|
|
|
On the negative side, the interface is \fIbizarre\fR \- so bizarre that
|
|
|
|
even sun itself gets it wrong in their code examples: The event polling
|
|
|
|
function sometimes returns events to the caller even though an error
|
|
|
|
occurred, but with no indication whether it has done so or not (yes, it's
|
|
|
|
even documented that way) \- deadly for edge-triggered interfaces where you
|
|
|
|
absolutely have to know whether an event occurred or not because you have
|
|
|
|
to re-arm the watcher.
|
|
|
|
.Sp
|
|
|
|
Fortunately libev seems to be able to work around these idiocies.
|
|
|
|
.Sp
|
|
|
|
This backend maps \f(CW\*(C`EV_READ\*(C'\fR and \f(CW\*(C`EV_WRITE\*(C'\fR in the same way as
|
|
|
|
\&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
|
|
|
|
.ie n .IP """EVBACKEND_ALL""" 4
|
|
|
|
.el .IP "\f(CWEVBACKEND_ALL\fR" 4
|
|
|
|
.IX Item "EVBACKEND_ALL"
|
|
|
|
Try all backends (even potentially broken ones that wouldn't be tried
|
|
|
|
with \f(CW\*(C`EVFLAG_AUTO\*(C'\fR). Since this is a mask, you can do stuff such as
|
|
|
|
\&\f(CW\*(C`EVBACKEND_ALL & ~EVBACKEND_KQUEUE\*(C'\fR.
|
|
|
|
.Sp
|
|
|
|
It is definitely not recommended to use this flag, use whatever
|
|
|
|
\&\f(CW\*(C`ev_recommended_backends ()\*(C'\fR returns, or simply do not specify a backend
|
|
|
|
at all.
|
|
|
|
.ie n .IP """EVBACKEND_MASK""" 4
|
|
|
|
.el .IP "\f(CWEVBACKEND_MASK\fR" 4
|
|
|
|
.IX Item "EVBACKEND_MASK"
|
|
|
|
Not a backend at all, but a mask to select all backend bits from a
|
|
|
|
\&\f(CW\*(C`flags\*(C'\fR value, in case you want to mask out any backends from a flags
|
|
|
|
value (e.g. when modifying the \f(CW\*(C`LIBEV_FLAGS\*(C'\fR environment variable).
|
|
|
|
.RE
|
|
|
|
.RS 4
|
|
|
|
.Sp
|
|
|
|
If one or more of the backend flags are or'ed into the flags value,
|
|
|
|
then only these backends will be tried (in the reverse order as listed
|
|
|
|
here). If none are specified, all backends in \f(CW\*(C`ev_recommended_backends
|
|
|
|
()\*(C'\fR will be tried.
|
|
|
|
.Sp
|
|
|
|
Example: Try to create a event loop that uses epoll and nothing else.
|
|
|
|
.Sp
|
|
|
|
.Vb 3
|
|
|
|
\& struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV);
|
|
|
|
\& if (!epoller)
|
|
|
|
\& fatal ("no epoll found here, maybe it hides under your chair");
|
|
|
|
.Ve
|
|
|
|
.Sp
|
|
|
|
Example: Use whatever libev has to offer, but make sure that kqueue is
|
|
|
|
used if available.
|
|
|
|
.Sp
|
|
|
|
.Vb 1
|
|
|
|
\& struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_KQUEUE);
|
|
|
|
.Ve
|
|
|
|
.RE
|
|
|
|
.IP "ev_loop_destroy (loop)" 4
|
|
|
|
.IX Item "ev_loop_destroy (loop)"
|
|
|
|
Destroys an event loop object (frees all memory and kernel state
|
|
|
|
etc.). None of the active event watchers will be stopped in the normal
|
|
|
|
sense, so e.g. \f(CW\*(C`ev_is_active\*(C'\fR might still return true. It is your
|
|
|
|
responsibility to either stop all watchers cleanly yourself \fIbefore\fR
|
|
|
|
calling this function, or cope with the fact afterwards (which is usually
|
|
|
|
the easiest thing, you can just ignore the watchers and/or \f(CW\*(C`free ()\*(C'\fR them
|
|
|
|
for example).
|
|
|
|
.Sp
|
|
|
|
Note that certain global state, such as signal state (and installed signal
|
|
|
|
handlers), will not be freed by this function, and related watchers (such
|
|
|
|
as signal and child watchers) would need to be stopped manually.
|
|
|
|
.Sp
|
|
|
|
This function is normally used on loop objects allocated by
|
|
|
|
\&\f(CW\*(C`ev_loop_new\*(C'\fR, but it can also be used on the default loop returned by
|
|
|
|
\&\f(CW\*(C`ev_default_loop\*(C'\fR, in which case it is not thread-safe.
|
|
|
|
.Sp
|
|
|
|
Note that it is not advisable to call this function on the default loop
|
|
|
|
except in the rare occasion where you really need to free its resources.
|
|
|
|
If you need dynamically allocated loops it is better to use \f(CW\*(C`ev_loop_new\*(C'\fR
|
|
|
|
and \f(CW\*(C`ev_loop_destroy\*(C'\fR.
|
|
|
|
.IP "ev_loop_fork (loop)" 4
|
|
|
|
.IX Item "ev_loop_fork (loop)"
|
|
|
|
This function sets a flag that causes subsequent \f(CW\*(C`ev_run\*(C'\fR iterations to
|
|
|
|
reinitialise the kernel state for backends that have one. Despite the
|
|
|
|
name, you can call it anytime, but it makes most sense after forking, in
|
|
|
|
the child process. You \fImust\fR call it (or use \f(CW\*(C`EVFLAG_FORKCHECK\*(C'\fR) in the
|
|
|
|
child before resuming or calling \f(CW\*(C`ev_run\*(C'\fR.
|
|
|
|
.Sp
|
|
|
|
Again, you \fIhave\fR to call it on \fIany\fR loop that you want to re-use after
|
|
|
|
a fork, \fIeven if you do not plan to use the loop in the parent\fR. This is
|
|
|
|
because some kernel interfaces *cough* \fIkqueue\fR *cough* do funny things
|
|
|
|
during fork.
|
|
|
|
.Sp
|
|
|
|
On the other hand, you only need to call this function in the child
|
|
|
|
process if and only if you want to use the event loop in the child. If
|
|
|
|
you just fork+exec or create a new loop in the child, you don't have to
|
|
|
|
call it at all (in fact, \f(CW\*(C`epoll\*(C'\fR is so badly broken that it makes a
|
|
|
|
difference, but libev will usually detect this case on its own and do a
|
|
|
|
costly reset of the backend).
|
|
|
|
.Sp
|
|
|
|
The function itself is quite fast and it's usually not a problem to call
|
|
|
|
it just in case after a fork.
|
|
|
|
.Sp
|
|
|
|
Example: Automate calling \f(CW\*(C`ev_loop_fork\*(C'\fR on the default loop when
|
|
|
|
using pthreads.
|
|
|
|
.Sp
|
|
|
|
.Vb 5
|
|
|
|
\& static void
|
|
|
|
\& post_fork_child (void)
|
|
|
|
\& {
|
|
|
|
\& ev_loop_fork (EV_DEFAULT);
|
|
|
|
\& }
|
|
|
|
\&
|
|
|
|
\& ...
|
|
|
|
\& pthread_atfork (0, 0, post_fork_child);
|
|
|
|
.Ve
|
|
|
|
.IP "int ev_is_default_loop (loop)" 4
|
|
|
|
.IX Item "int ev_is_default_loop (loop)"
|
|
|
|
Returns true when the given loop is, in fact, the default loop, and false
|
|
|
|
otherwise.
|
|
|
|
.IP "unsigned int ev_iteration (loop)" 4
|
|
|
|
.IX Item "unsigned int ev_iteration (loop)"
|
|
|
|
Returns the current iteration count for the event loop, which is identical
|
|
|
|
to the number of times libev did poll for new events. It starts at \f(CW0\fR
|
|
|
|
and happily wraps around with enough iterations.
|
|
|
|
.Sp
|
|
|
|
This value can sometimes be useful as a generation counter of sorts (it
|
|
|
|
\&\*(L"ticks\*(R" the number of loop iterations), as it roughly corresponds with
|
|
|
|
\&\f(CW\*(C`ev_prepare\*(C'\fR and \f(CW\*(C`ev_check\*(C'\fR calls \- and is incremented between the
|
|