|
|
@ -1,4 +1,4 @@ |
|
|
|
.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) |
|
|
|
.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.30) |
|
|
|
.\" |
|
|
|
.\" Standard preamble: |
|
|
|
.\" ======================================================================== |
|
|
@ -38,6 +38,8 @@ |
|
|
|
. ds PI \(*p |
|
|
|
. ds L" `` |
|
|
|
. ds R" '' |
|
|
|
. ds C` |
|
|
|
. ds C' |
|
|
|
'br\} |
|
|
|
.\" |
|
|
|
.\" Escape single quotes in literal strings from groff's Unicode transform. |
|
|
@ -48,17 +50,24 @@ |
|
|
|
.\" 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" |
|
|
|
.\" |
|
|
|
.\" Avoid warning from groff about undefined register 'F'. |
|
|
|
.de IX |
|
|
|
.. |
|
|
|
. nr % 0 |
|
|
|
. rr F |
|
|
|
.\} |
|
|
|
.el \{\ |
|
|
|
. de IX |
|
|
|
.nr rF 0 |
|
|
|
.if \n(.g .if rF .nr rF 1 |
|
|
|
.if (\n(rF:(\n(.g==0)) \{ |
|
|
|
. if \nF \{ |
|
|
|
. de IX |
|
|
|
. tm Index:\\$1\t\\n%\t"\\$2" |
|
|
|
.. |
|
|
|
. if !\nF==2 \{ |
|
|
|
. nr % 0 |
|
|
|
. nr F 2 |
|
|
|
. \} |
|
|
|
. \} |
|
|
|
.\} |
|
|
|
.rr rF |
|
|
|
.\" |
|
|
|
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). |
|
|
|
.\" Fear. Run. Save yourself. No user-serviceable parts. |
|
|
@ -124,7 +133,7 @@ |
|
|
|
.\" ======================================================================== |
|
|
|
.\" |
|
|
|
.IX Title "LIBEV 3" |
|
|
|
.TH LIBEV 3 "2015-07-28" "libev-2.2.3" "libev - high performance full featured event loop" |
|
|
|
.TH LIBEV 3 "2015-12-20" "libev-4.20" "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 |
|
|
@ -136,7 +145,7 @@ libev \- a high performance full\-featured event loop written in C |
|
|
|
.Vb 1 |
|
|
|
\& #include <ev.h> |
|
|
|
.Ve |
|
|
|
.SS "\s-1EXAMPLE\s0 \s-1PROGRAM\s0" |
|
|
|
.SS "\s-1EXAMPLE PROGRAM\s0" |
|
|
|
.IX Subsection "EXAMPLE PROGRAM" |
|
|
|
.Vb 2 |
|
|
|
\& // a single header file is required |
|
|
@ -214,9 +223,9 @@ throughout this document. |
|
|
|
.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". |
|
|
|
reading \*(L"\s-1ANATOMY OF A WATCHER\*(R"\s0, then the \*(L"\s-1EXAMPLE PROGRAM\*(R"\s0 above and |
|
|
|
look up the missing functions in \*(L"\s-1GLOBAL FUNCTIONS\*(R"\s0 and the \f(CW\*(C`ev_io\*(C'\fR and |
|
|
|
\&\f(CW\*(C`ev_timer\*(C'\fR sections in \*(L"\s-1WATCHER TYPES\*(R"\s0. |
|
|
|
.SH "ABOUT LIBEV" |
|
|
|
.IX Header "ABOUT LIBEV" |
|
|
|
Libev is an event loop: you register interest in certain events (such as a |
|
|
@ -257,7 +266,7 @@ more info about various configuration options please have a look at |
|
|
|
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" |
|
|
|
.SS "\s-1TIME REPRESENTATION\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 |
|
|
@ -534,8 +543,8 @@ 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. |
|
|
|
forget about forgetting to tell libev about forking, although you still |
|
|
|
have to ignore \f(CW\*(C`SIGPIPE\*(C'\fR) 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. |
|
|
@ -576,7 +585,7 @@ It's also required by \s-1POSIX\s0 in a threaded program, as libev calls |
|
|
|
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)" |
|
|
|
.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 |
|
|
@ -595,7 +604,7 @@ This backend maps \f(CW\*(C`EV_READ\*(C'\fR to the \f(CW\*(C`readfds\*(C'\fR set |
|
|
|
\&\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)" |
|
|
|
.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 |
|
|
@ -607,7 +616,7 @@ This backend maps \f(CW\*(C`EV_READ\*(C'\fR to \f(CW\*(C`POLLIN | POLLERR | POLL |
|
|
|
\&\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)" |
|
|
|
.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 |
|
|
@ -670,7 +679,7 @@ This backend maps \f(CW\*(C`EV_READ\*(C'\fR and \f(CW\*(C`EV_WRITE\*(C'\fR in th |
|
|
|
\&\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)" |
|
|
|
.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 |
|
|
@ -700,7 +709,7 @@ 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. |
|
|
|
also broken on \s-1OS X\s0)) 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 |
|
|
@ -714,7 +723,7 @@ 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)" |
|
|
|
.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 |
|
|
@ -810,6 +819,9 @@ watchers (except inside an \f(CW\*(C`ev_prepare\*(C'\fR callback), but it makes |
|
|
|
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 |
|
|
|
In addition, if you want to reuse a loop (via this function or |
|
|
|
\&\f(CW\*(C`EVFLAG_FORKCHECK\*(C'\fR), you \fIalso\fR have to ignore \f(CW\*(C`SIGPIPE\*(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 |
|
|
@ -1357,7 +1369,7 @@ callbacks is well-written it can just attempt the operation and cope with |
|
|
|
the error from \fIread()\fR or \fIwrite()\fR. This will not work in multi-threaded |
|
|
|
programs, though, as the fd could already be closed and reused for another |
|
|
|
thing, so beware. |
|
|
|
.SS "\s-1GENERIC\s0 \s-1WATCHER\s0 \s-1FUNCTIONS\s0" |
|
|
|
.SS "\s-1GENERIC WATCHER FUNCTIONS\s0" |
|
|
|
.IX Subsection "GENERIC WATCHER FUNCTIONS" |
|
|
|
.ie n .IP """ev_init"" (ev_TYPE *watcher, callback)" 4 |
|
|
|
.el .IP "\f(CWev_init\fR (ev_TYPE *watcher, callback)" 4 |
|
|
@ -1475,7 +1487,7 @@ or might not have been clamped to the valid range. |
|
|
|
The default priority used by watchers when no priority has been set is |
|
|
|
always \f(CW0\fR, which is supposed to not be too high and not be too low :). |
|
|
|
.Sp |
|
|
|
See \*(L"\s-1WATCHER\s0 \s-1PRIORITY\s0 \s-1MODELS\s0\*(R", below, for a more thorough treatment of |
|
|
|
See \*(L"\s-1WATCHER PRIORITY MODELS\*(R"\s0, below, for a more thorough treatment of |
|
|
|
priorities. |
|
|
|
.IP "ev_invoke (loop, ev_TYPE *watcher, int revents)" 4 |
|
|
|
.IX Item "ev_invoke (loop, ev_TYPE *watcher, int revents)" |
|
|
@ -1505,9 +1517,9 @@ not started in the first place. |
|
|
|
See also \f(CW\*(C`ev_feed_fd_event\*(C'\fR and \f(CW\*(C`ev_feed_signal_event\*(C'\fR for related |
|
|
|
functions that do not need a watcher. |
|
|
|
.PP |
|
|
|
See also the \*(L"\s-1ASSOCIATING\s0 \s-1CUSTOM\s0 \s-1DATA\s0 \s-1WITH\s0 A \s-1WATCHER\s0\*(R" and \*(L"\s-1BUILDING\s0 \s-1YOUR\s0 |
|
|
|
\&\s-1OWN\s0 \s-1COMPOSITE\s0 \s-1WATCHERS\s0\*(R" idioms. |
|
|
|
.SS "\s-1WATCHER\s0 \s-1STATES\s0" |
|
|
|
See also the \*(L"\s-1ASSOCIATING CUSTOM DATA WITH A WATCHER\*(R"\s0 and \*(L"\s-1BUILDING YOUR |
|
|
|
OWN COMPOSITE WATCHERS\*(R"\s0 idioms. |
|
|
|
.SS "\s-1WATCHER STATES\s0" |
|
|
|
.IX Subsection "WATCHER STATES" |
|
|
|
There are various watcher states mentioned throughout this manual \- |
|
|
|
active, pending and so on. In this section these states and the rules to |
|
|
@ -1560,7 +1572,7 @@ While stopped (and not pending) the watcher is essentially in the |
|
|
|
initialised state, that is, it can be reused, moved, modified in any way |
|
|
|
you wish (but when you trash the memory block, you need to \f(CW\*(C`ev_TYPE_init\*(C'\fR |
|
|
|
it again). |
|
|
|
.SS "\s-1WATCHER\s0 \s-1PRIORITY\s0 \s-1MODELS\s0" |
|
|
|
.SS "\s-1WATCHER PRIORITY MODELS\s0" |
|
|
|
.IX Subsection "WATCHER PRIORITY MODELS" |
|
|
|
Many event loops support \fIwatcher priorities\fR, which are usually small |
|
|
|
integers that influence the ordering of event callback invocation |
|
|
@ -1768,7 +1780,7 @@ wish to read \- you would first have to request some data. |
|
|
|
Since files are typically not-so-well supported by advanced notification |
|
|
|
mechanism, libev tries hard to emulate \s-1POSIX\s0 behaviour with respect |
|
|
|
to files, even though you should not use it. The reason for this is |
|
|
|
convenience: sometimes you want to watch \s-1STDIN\s0 or \s-1STDOUT\s0, which is |
|
|
|
convenience: sometimes you want to watch \s-1STDIN\s0 or \s-1STDOUT,\s0 which is |
|
|
|
usually a tty, often a pipe, but also sometimes files or special devices |
|
|
|
(for example, \f(CW\*(C`epoll\*(C'\fR on Linux works with \fI/dev/random\fR but not with |
|
|
|
\&\fI/dev/urandom\fR), and even though the file might better be served with |
|
|
@ -1776,7 +1788,7 @@ asynchronous I/O instead of with non-blocking I/O, it is still useful when |
|
|
|
it \*(L"just works\*(R" instead of freezing. |
|
|
|
.PP |
|
|
|
So avoid file descriptors pointing to files when you know it (e.g. use |
|
|
|
libeio), but use them when it is convenient, e.g. for \s-1STDIN/STDOUT\s0, or |
|
|
|
libeio), but use them when it is convenient, e.g. for \s-1STDIN/STDOUT,\s0 or |
|
|
|
when you rarely read from a file instead of from a socket, and want to |
|
|
|
reuse the same code path. |
|
|
|
.PP |
|
|
@ -1796,17 +1808,17 @@ To support fork in your child processes, you have to call \f(CW\*(C`ev_loop_fork |
|
|
|
.PP |
|
|
|
While not really specific to libev, it is easy to forget about \f(CW\*(C`SIGPIPE\*(C'\fR: |
|
|
|
when writing to a pipe whose other end has been closed, your program gets |
|
|
|
sent a \s-1SIGPIPE\s0, which, by default, aborts your program. For most programs |
|
|
|
sent a \s-1SIGPIPE,\s0 which, by default, aborts your program. For most programs |
|
|
|
this is sensible behaviour, for daemons, this is usually undesirable. |
|
|
|
.PP |
|
|
|
So when you encounter spurious, unexplained daemon exits, make sure you |
|
|
|
ignore \s-1SIGPIPE\s0 (and maybe make sure you log the exit status of your daemon |
|
|
|
ignore \s-1SIGPIPE \s0(and maybe make sure you log the exit status of your daemon |
|
|
|
somewhere, as that would have given you a big clue). |
|
|
|
.PP |
|
|
|
\fIThe special problem of \fIaccept()\fIing when you can't\fR |
|
|
|
.IX Subsection "The special problem of accept()ing when you can't" |
|
|
|
.PP |
|
|
|
Many implementations of the \s-1POSIX\s0 \f(CW\*(C`accept\*(C'\fR function (for example, |
|
|
|
Many implementations of the \s-1POSIX \s0\f(CW\*(C`accept\*(C'\fR function (for example, |
|
|
|
found in post\-2004 Linux) have the peculiar behaviour of not removing a |
|
|
|
connection from the pending queue in all error cases. |
|
|
|
.PP |
|
|
@ -2423,7 +2435,7 @@ ignored. Instead, each time the periodic watcher gets scheduled, the |
|
|
|
reschedule callback will be called with the watcher as first, and the |
|
|
|
current time as second argument. |
|
|
|
.Sp |
|
|
|
\&\s-1NOTE:\s0 \fIThis callback \s-1MUST\s0 \s-1NOT\s0 stop or destroy any periodic watcher, ever, |
|
|
|
\&\s-1NOTE: \s0\fIThis callback \s-1MUST NOT\s0 stop or destroy any periodic watcher, ever, |
|
|
|
or make \s-1ANY\s0 other event loop modifications whatsoever, unless explicitly |
|
|
|
allowed by documentation here\fR. |
|
|
|
.Sp |
|
|
@ -2447,7 +2459,7 @@ It must return the next time to trigger, based on the passed time value |
|
|
|
will usually be called just before the callback will be triggered, but |
|
|
|
might be called at other times, too. |
|
|
|
.Sp |
|
|
|
\&\s-1NOTE:\s0 \fIThis callback must always return a time that is higher than or |
|
|
|
\&\s-1NOTE: \s0\fIThis callback must always return a time that is higher than or |
|
|
|
equal to the passed \f(CI\*(C`now\*(C'\fI value\fR. |
|
|
|
.Sp |
|
|
|
This can be used to create very complex timers, such as a timer that |
|
|
@ -2582,7 +2594,7 @@ to install a fork handler with \f(CW\*(C`pthread_atfork\*(C'\fR that resets it. |
|
|
|
catch fork calls done by libraries (such as the libc) as well. |
|
|
|
.PP |
|
|
|
In current versions of libev, the signal will not be blocked indefinitely |
|
|
|
unless you use the \f(CW\*(C`signalfd\*(C'\fR \s-1API\s0 (\f(CW\*(C`EV_SIGNALFD\*(C'\fR). While this reduces |
|
|
|
unless you use the \f(CW\*(C`signalfd\*(C'\fR \s-1API \s0(\f(CW\*(C`EV_SIGNALFD\*(C'\fR). While this reduces |
|
|
|
the window of opportunity for problems, it will not go away, as libev |
|
|
|
\&\fIhas\fR to modify the signal mask, at least temporarily. |
|
|
|
.PP |
|
|
@ -2622,7 +2634,7 @@ The signal the watcher watches out for. |
|
|
|
\fIExamples\fR |
|
|
|
.IX Subsection "Examples" |
|
|
|
.PP |
|
|
|
Example: Try to exit cleanly on \s-1SIGINT\s0. |
|
|
|
Example: Try to exit cleanly on \s-1SIGINT.\s0 |
|
|
|
.PP |
|
|
|
.Vb 5 |
|
|
|
\& static void |
|
|
@ -2789,7 +2801,7 @@ support disabled by default, you get the 32 bit version of the stat |
|
|
|
structure. When using the library from programs that change the \s-1ABI\s0 to |
|
|
|
use 64 bit file offsets the programs will fail. In that case you have to |
|
|
|
compile libev with the same flags to get binary compatibility. This is |
|
|
|
obviously the case with any flags that change the \s-1ABI\s0, but the problem is |
|
|
|
obviously the case with any flags that change the \s-1ABI,\s0 but the problem is |
|
|
|
most noticeably displayed with ev_stat and large file support. |
|
|
|
.PP |
|
|
|
The solution for this is to lobby your distribution maker to make large |
|
|
@ -3230,7 +3242,7 @@ callbacks, and only destroy/create the watchers in the prepare watcher. |
|
|
|
Method 4: Do not use a prepare or check watcher because the module you |
|
|
|
want to embed is not flexible enough to support it. Instead, you can |
|
|
|
override their poll function. The drawback with this solution is that the |
|
|
|
main loop is now no longer controllable by \s-1EV\s0. The \f(CW\*(C`Glib::EV\*(C'\fR module uses |
|
|
|
main loop is now no longer controllable by \s-1EV.\s0 The \f(CW\*(C`Glib::EV\*(C'\fR module uses |
|
|
|
this approach, effectively embedding \s-1EV\s0 as a client into the horrible |
|
|
|
libglib event loop. |
|
|
|
.PP |
|
|
@ -3657,7 +3669,7 @@ value passed to \f(CW\*(C`ev_once\*(C'\fR. Note that it is possible to receive \ |
|
|
|
a timeout and an io event at the same time \- you probably should give io |
|
|
|
events precedence. |
|
|
|
.Sp |
|
|
|
Example: wait up to ten seconds for data to appear on \s-1STDIN_FILENO\s0. |
|
|
|
Example: wait up to ten seconds for data to appear on \s-1STDIN_FILENO.\s0 |
|
|
|
.Sp |
|
|
|
.Vb 7 |
|
|
|
\& static void stdin_ready (int revents, void *arg) |
|
|
@ -3683,7 +3695,7 @@ which is async-safe. |
|
|
|
This section explains some common idioms that are not immediately |
|
|
|
obvious. Note that examples are sprinkled over the whole manual, and this |
|
|
|
section only contains stuff that wouldn't fit anywhere else. |
|
|
|
.SS "\s-1ASSOCIATING\s0 \s-1CUSTOM\s0 \s-1DATA\s0 \s-1WITH\s0 A \s-1WATCHER\s0" |
|
|
|
.SS "\s-1ASSOCIATING CUSTOM DATA WITH A WATCHER\s0" |
|
|
|
.IX Subsection "ASSOCIATING CUSTOM DATA WITH A WATCHER" |
|
|
|
Each watcher has, by default, a \f(CW\*(C`void *data\*(C'\fR member that you can read |
|
|
|
or modify at any time: libev will completely ignore it. This can be used |
|
|
@ -3719,7 +3731,7 @@ can cast it back to your own type: |
|
|
|
.PP |
|
|
|
More interesting and less C\-conformant ways of casting your callback |
|
|
|
function type instead have been omitted. |
|
|
|
.SS "\s-1BUILDING\s0 \s-1YOUR\s0 \s-1OWN\s0 \s-1COMPOSITE\s0 \s-1WATCHERS\s0" |
|
|
|
.SS "\s-1BUILDING YOUR OWN COMPOSITE WATCHERS\s0" |
|
|
|
.IX Subsection "BUILDING YOUR OWN COMPOSITE WATCHERS" |
|
|
|
Another common scenario is to use some data structure with multiple |
|
|
|
embedded watchers, in effect creating your own watcher that combines |
|
|
@ -3757,7 +3769,7 @@ real programmers): |
|
|
|
\& (((char *)w) \- offsetof (struct my_biggy, t2)); |
|
|
|
\& } |
|
|
|
.Ve |
|
|
|
.SS "\s-1AVOIDING\s0 \s-1FINISHING\s0 \s-1BEFORE\s0 \s-1RETURNING\s0" |
|
|
|
.SS "\s-1AVOIDING FINISHING BEFORE RETURNING\s0" |
|
|
|
.IX Subsection "AVOIDING FINISHING BEFORE RETURNING" |
|
|
|
Often you have structures like this in event-based programs: |
|
|
|
.PP |
|
|
@ -3800,7 +3812,7 @@ pushing it into the pending queue: |
|
|
|
.PP |
|
|
|
This way, \f(CW\*(C`start_new_request\*(C'\fR can safely return before the callback is |
|
|
|
invoked, while not delaying callback invocation too much. |
|
|
|
.SS "\s-1MODEL/NESTED\s0 \s-1EVENT\s0 \s-1LOOP\s0 \s-1INVOCATIONS\s0 \s-1AND\s0 \s-1EXIT\s0 \s-1CONDITIONS\s0" |
|
|
|
.SS "\s-1MODEL/NESTED EVENT LOOP INVOCATIONS AND EXIT CONDITIONS\s0" |
|
|
|
.IX Subsection "MODEL/NESTED EVENT LOOP INVOCATIONS AND EXIT CONDITIONS" |
|
|
|
Often (especially in \s-1GUI\s0 toolkits) there are places where you have |
|
|
|
\&\fImodal\fR interaction, which is most easily implemented by recursively |
|
|
@ -3842,7 +3854,7 @@ To exit from any of these loops, just set the corresponding exit variable: |
|
|
|
\& // exit both |
|
|
|
\& exit_main_loop = exit_nested_loop = 1; |
|
|
|
.Ve |
|
|
|
.SS "\s-1THREAD\s0 \s-1LOCKING\s0 \s-1EXAMPLE\s0" |
|
|
|
.SS "\s-1THREAD LOCKING EXAMPLE\s0" |
|
|
|
.IX Subsection "THREAD LOCKING EXAMPLE" |
|
|
|
Here is a fictitious example of how to run an event loop in a different |
|
|
|
thread from where callbacks are being invoked and watchers are |
|
|
@ -3993,7 +4005,7 @@ Note that sending the \f(CW\*(C`ev_async\*(C'\fR watcher is required because oth |
|
|
|
an event loop currently blocking in the kernel will have no knowledge |
|
|
|
about the newly added timer. By waking up the loop it will pick up any new |
|
|
|
watchers in the next event loop iteration. |
|
|
|
.SS "\s-1THREADS\s0, \s-1COROUTINES\s0, \s-1CONTINUATIONS\s0, \s-1QUEUES\s0... \s-1INSTEAD\s0 \s-1OF\s0 \s-1CALLBACKS\s0" |
|
|
|
.SS "\s-1THREADS, COROUTINES, CONTINUATIONS, QUEUES... INSTEAD OF CALLBACKS\s0" |
|
|
|
.IX Subsection "THREADS, COROUTINES, CONTINUATIONS, QUEUES... INSTEAD OF CALLBACKS" |
|
|
|
While the overhead of a callback that e.g. schedules a thread is small, it |
|
|
|
is still an overhead. If you embed libev, and your main usage is with some |
|
|
@ -4039,7 +4051,7 @@ instead of storing a coroutine, you store the queue object and instead of |
|
|
|
switching to a coroutine, you push the watcher onto the queue and notify |
|
|
|
any waiters. |
|
|
|
.PP |
|
|
|
To embed libev, see \*(L"\s-1EMBEDDING\s0\*(R", but in short, it's easiest to create two |
|
|
|
To embed libev, see \*(L"\s-1EMBEDDING\*(R"\s0, but in short, it's easiest to create two |
|
|
|
files, \fImy_ev.h\fR and \fImy_ev.c\fR that include the respective libev files: |
|
|
|
.PP |
|
|
|
.Vb 4 |
|
|
@ -4344,7 +4356,7 @@ to \f(CW\*(C`libadns\*(C'\fR (\f(CW\*(C`EV::ADNS\*(C'\fR, but \f(CW\*(C`AnyEvent |
|
|
|
\&\f(CW\*(C`Net::SNMP\*(C'\fR (\f(CW\*(C`Net::SNMP::EV\*(C'\fR) and the \f(CW\*(C`libglib\*(C'\fR event core (\f(CW\*(C`Glib::EV\*(C'\fR |
|
|
|
and \f(CW\*(C`EV::Glib\*(C'\fR). |
|
|
|
.Sp |
|
|
|
It can be found and installed via \s-1CPAN\s0, its homepage is at |
|
|
|
It can be found and installed via \s-1CPAN,\s0 its homepage is at |
|
|
|
<http://software.schmorp.de/pkg/EV>. |
|
|
|
.IP "Python" 4 |
|
|
|
.IX Item "Python" |
|
|
@ -4362,7 +4374,7 @@ makes rev work even on mingw. |
|
|
|
.IP "Haskell" 4 |
|
|
|
.IX Item "Haskell" |
|
|
|
A haskell binding to libev is available at |
|
|
|
http://hackage.haskell.org/cgi\-bin/hackage\-scripts/package/hlibev <http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hlibev>. |
|
|
|
<http://hackage.haskell.org/cgi\-bin/hackage\-scripts/package/hlibev>. |
|
|
|
.IP "D" 4 |
|
|
|
.IX Item "D" |
|
|
|
Leandro Lucarella has written a D language binding (\fIev.d\fR) for libev, to |
|
|
@ -4370,12 +4382,12 @@ be found at <http://www.llucax.com.ar/proj/ev.d/index.html>. |
|
|
|
.IP "Ocaml" 4 |
|
|
|
.IX Item "Ocaml" |
|
|
|
Erkki Seppala has written Ocaml bindings for libev, to be found at |
|
|
|
http://modeemi.cs.tut.fi/~flux/software/ocaml\-ev/ <http://modeemi.cs.tut.fi/~flux/software/ocaml-ev/>. |
|
|
|
<http://modeemi.cs.tut.fi/~flux/software/ocaml\-ev/>. |
|
|
|
.IP "Lua" 4 |
|
|
|
.IX Item "Lua" |
|
|
|
Brian Maher has written a partial interface to libev for lua (at the |
|
|
|
time of this writing, only \f(CW\*(C`ev_io\*(C'\fR and \f(CW\*(C`ev_timer\*(C'\fR), to be found at |
|
|
|
http://github.com/brimworks/lua\-ev <http://github.com/brimworks/lua-ev>. |
|
|
|
<http://github.com/brimworks/lua\-ev>. |
|
|
|
.IP "Javascript" 4 |
|
|
|
.IX Item "Javascript" |
|
|
|
Node.js (<http://nodejs.org>) uses libev as the underlying event library. |
|
|
@ -4474,7 +4486,7 @@ libev somewhere in your source tree). |
|
|
|
Depending on what features you need you need to include one or more sets of files |
|
|
|
in your application. |
|
|
|
.PP |
|
|
|
\fI\s-1CORE\s0 \s-1EVENT\s0 \s-1LOOP\s0\fR |
|
|
|
\fI\s-1CORE EVENT LOOP\s0\fR |
|
|
|
.IX Subsection "CORE EVENT LOOP" |
|
|
|
.PP |
|
|
|
To include only the libev core (all the \f(CW\*(C`ev_*\*(C'\fR functions), with manual |
|
|
@ -4487,7 +4499,7 @@ configuration (no autoconf): |
|
|
|
.PP |
|
|
|
This will automatically include \fIev.h\fR, too, and should be done in a |
|
|
|
single C source file only to provide the function implementations. To use |
|
|
|
it, do the same for \fIev.h\fR in all files wishing to use this \s-1API\s0 (best |
|
|
|
it, do the same for \fIev.h\fR in all files wishing to use this \s-1API \s0(best |
|
|
|
done by writing a wrapper around \fIev.h\fR that you can include instead and |
|
|
|
where you can put other configuration options): |
|
|
|
.PP |
|
|
@ -4521,10 +4533,10 @@ in your include path (e.g. in libev/ when using \-Ilibev): |
|
|
|
\&\fIev.c\fR includes the backend files directly when enabled, so you only need |
|
|
|
to compile this single file. |
|
|
|
.PP |
|
|
|
\fI\s-1LIBEVENT\s0 \s-1COMPATIBILITY\s0 \s-1API\s0\fR |
|
|
|
\fI\s-1LIBEVENT COMPATIBILITY API\s0\fR |
|
|
|
.IX Subsection "LIBEVENT COMPATIBILITY API" |
|
|
|
.PP |
|
|
|
To include the libevent compatibility \s-1API\s0, also include: |
|
|
|
To include the libevent compatibility \s-1API,\s0 also include: |
|
|
|
.PP |
|
|
|
.Vb 1 |
|
|
|
\& #include "event.c" |
|
|
@ -4536,7 +4548,7 @@ in the file including \fIev.c\fR, and: |
|
|
|
\& #include "event.h" |
|
|
|
.Ve |
|
|
|
.PP |
|
|
|
in the files that want to use the libevent \s-1API\s0. This also includes \fIev.h\fR. |
|
|
|
in the files that want to use the libevent \s-1API.\s0 This also includes \fIev.h\fR. |
|
|
|
.PP |
|
|
|
You need the following additional files for this: |
|
|
|
.PP |
|
|
@ -4545,7 +4557,7 @@ You need the following additional files for this: |
|
|
|
\& event.c |
|
|
|
.Ve |
|
|
|
.PP |
|
|
|
\fI\s-1AUTOCONF\s0 \s-1SUPPORT\s0\fR |
|
|
|
\fI\s-1AUTOCONF SUPPORT\s0\fR |
|
|
|
.IX Subsection "AUTOCONF SUPPORT" |
|
|
|
.PP |
|
|
|
Instead of using \f(CW\*(C`EV_STANDALONE=1\*(C'\fR and providing your configuration in |
|
|
@ -4558,19 +4570,19 @@ For this of course you need the m4 file: |
|
|
|
.Vb 1 |
|
|
|
\& libev.m4 |
|
|
|
.Ve |
|
|
|
.SS "\s-1PREPROCESSOR\s0 \s-1SYMBOLS/MACROS\s0" |
|
|
|
.SS "\s-1PREPROCESSOR SYMBOLS/MACROS\s0" |
|
|
|
.IX Subsection "PREPROCESSOR SYMBOLS/MACROS" |
|
|
|
Libev can be configured via a variety of preprocessor symbols you have to |
|
|
|
define before including (or compiling) any of its files. The default in |
|
|
|
the absence of autoconf is documented for every option. |
|
|
|
.PP |
|
|
|
Symbols marked with \*(L"(h)\*(R" do not change the \s-1ABI\s0, and can have different |
|
|
|
Symbols marked with \*(L"(h)\*(R" do not change the \s-1ABI,\s0 and can have different |
|
|
|
values when compiling libev vs. including \fIev.h\fR, so it is permissible |
|
|
|
to redefine them before including \fIev.h\fR without breaking compatibility |
|
|
|
to a compiled library. All other symbols change the \s-1ABI\s0, which means all |
|
|
|
to a compiled library. All other symbols change the \s-1ABI,\s0 which means all |
|
|
|
users of libev and the libev code itself must be compiled with compatible |
|
|
|
settings. |
|
|
|
.IP "\s-1EV_COMPAT3\s0 (h)" 4 |
|
|
|
.IP "\s-1EV_COMPAT3 \s0(h)" 4 |
|
|
|
.IX Item "EV_COMPAT3 (h)" |
|
|
|
Backwards compatibility is a major concern for libev. This is why this |
|
|
|
release of libev comes with wrappers for the functions and symbols that |
|
|
@ -4585,7 +4597,7 @@ typedef in that case. |
|
|
|
In some future version, the default for \f(CW\*(C`EV_COMPAT3\*(C'\fR will become \f(CW0\fR, |
|
|
|
and in some even more future version the compatibility code will be |
|
|
|
removed completely. |
|
|
|
.IP "\s-1EV_STANDALONE\s0 (h)" 4 |
|
|
|
.IP "\s-1EV_STANDALONE \s0(h)" 4 |
|
|
|
.IX Item "EV_STANDALONE (h)" |
|
|
|
Must always be \f(CW1\fR if you do not use autoconf configuration, which |
|
|
|
keeps libev from including \fIconfig.h\fR, and it also defines dummy |
|
|
@ -4753,21 +4765,21 @@ watchers. |
|
|
|
.Sp |
|
|
|
In the absence of this define, libev will use \f(CW\*(C`sig_atomic_t volatile\*(C'\fR |
|
|
|
(from \fIsignal.h\fR), which is usually good enough on most platforms. |
|
|
|
.IP "\s-1EV_H\s0 (h)" 4 |
|
|
|
.IP "\s-1EV_H \s0(h)" 4 |
|
|
|
.IX Item "EV_H (h)" |
|
|
|
The name of the \fIev.h\fR header file used to include it. The default if |
|
|
|
undefined is \f(CW"ev.h"\fR in \fIevent.h\fR, \fIev.c\fR and \fIev++.h\fR. This can be |
|
|
|
used to virtually rename the \fIev.h\fR header file in case of conflicts. |
|
|
|
.IP "\s-1EV_CONFIG_H\s0 (h)" 4 |
|
|
|
.IP "\s-1EV_CONFIG_H \s0(h)" 4 |
|
|
|
.IX Item "EV_CONFIG_H (h)" |
|
|
|
If \f(CW\*(C`EV_STANDALONE\*(C'\fR isn't \f(CW1\fR, this variable can be used to override |
|
|
|
\&\fIev.c\fR's idea of where to find the \fIconfig.h\fR file, similarly to |
|
|
|
\&\f(CW\*(C`EV_H\*(C'\fR, above. |
|
|
|
.IP "\s-1EV_EVENT_H\s0 (h)" 4 |
|
|
|
.IP "\s-1EV_EVENT_H \s0(h)" 4 |
|
|
|
.IX Item "EV_EVENT_H (h)" |
|
|
|
Similarly to \f(CW\*(C`EV_H\*(C'\fR, this macro can be used to override \fIevent.c\fR's idea |
|
|
|
of how the \fIevent.h\fR header can be found, the default is \f(CW"event.h"\fR. |
|
|
|
.IP "\s-1EV_PROTOTYPES\s0 (h)" 4 |
|
|
|
.IP "\s-1EV_PROTOTYPES \s0(h)" 4 |
|
|
|
.IX Item "EV_PROTOTYPES (h)" |
|
|
|
If defined to be \f(CW0\fR, then \fIev.h\fR will not define any function |
|
|
|
prototypes, but still define all the structs and other symbols. This is |
|
|
@ -4801,8 +4813,8 @@ and time, so using the defaults of five priorities (\-2 .. +2) is usually |
|
|
|
fine. |
|
|
|
.Sp |
|
|
|
If your embedding application does not need any priorities, defining these |
|
|
|
both to \f(CW0\fR will save some memory and \s-1CPU\s0. |
|
|
|
.IP "\s-1EV_PERIODIC_ENABLE\s0, \s-1EV_IDLE_ENABLE\s0, \s-1EV_EMBED_ENABLE\s0, \s-1EV_STAT_ENABLE\s0, \s-1EV_PREPARE_ENABLE\s0, \s-1EV_CHECK_ENABLE\s0, \s-1EV_FORK_ENABLE\s0, \s-1EV_SIGNAL_ENABLE\s0, \s-1EV_ASYNC_ENABLE\s0, \s-1EV_CHILD_ENABLE\s0." 4 |
|
|
|
both to \f(CW0\fR will save some memory and \s-1CPU.\s0 |
|
|
|
.IP "\s-1EV_PERIODIC_ENABLE, EV_IDLE_ENABLE, EV_EMBED_ENABLE, EV_STAT_ENABLE, EV_PREPARE_ENABLE, EV_CHECK_ENABLE, EV_FORK_ENABLE, EV_SIGNAL_ENABLE, EV_ASYNC_ENABLE, EV_CHILD_ENABLE.\s0" 4 |
|
|
|
.IX Item "EV_PERIODIC_ENABLE, EV_IDLE_ENABLE, EV_EMBED_ENABLE, EV_STAT_ENABLE, EV_PREPARE_ENABLE, EV_CHECK_ENABLE, EV_FORK_ENABLE, EV_SIGNAL_ENABLE, EV_ASYNC_ENABLE, EV_CHILD_ENABLE." |
|
|
|
If undefined or defined to be \f(CW1\fR (and the platform supports it), then |
|
|
|
the respective watcher type is supported. If defined to be \f(CW0\fR, then it |
|
|
@ -4986,10 +4998,10 @@ For example, the perl \s-1EV\s0 module uses something like this: |
|
|
|
\& SV *self; /* contains this struct */ \e |
|
|
|
\& SV *cb_sv, *fh /* note no trailing ";" */ |
|
|
|
.Ve |
|
|
|
.IP "\s-1EV_CB_DECLARE\s0 (type)" 4 |
|
|
|
.IP "\s-1EV_CB_DECLARE \s0(type)" 4 |
|
|
|
.IX Item "EV_CB_DECLARE (type)" |
|
|
|
.PD 0 |
|
|
|
.IP "\s-1EV_CB_INVOKE\s0 (watcher, revents)" 4 |
|
|
|
.IP "\s-1EV_CB_INVOKE \s0(watcher, revents)" 4 |
|
|
|
.IX Item "EV_CB_INVOKE (watcher, revents)" |
|
|
|
.IP "ev_set_cb (ev, cb)" 4 |
|
|
|
.IX Item "ev_set_cb (ev, cb)" |
|
|
@ -5000,9 +5012,9 @@ definition and a statement, respectively. See the \fIev.h\fR header file for |
|
|
|
their default definitions. One possible use for overriding these is to |
|
|
|
avoid the \f(CW\*(C`struct ev_loop *\*(C'\fR as first argument in all cases, or to use |
|
|
|
method calls instead of plain function calls in \*(C+. |
|
|
|
.SS "\s-1EXPORTED\s0 \s-1API\s0 \s-1SYMBOLS\s0" |
|
|
|
.SS "\s-1EXPORTED API SYMBOLS\s0" |
|
|
|
.IX Subsection "EXPORTED API SYMBOLS" |
|
|
|
If you need to re-export the \s-1API\s0 (e.g. via a \s-1DLL\s0) and you need a list of |
|
|
|
If you need to re-export the \s-1API \s0(e.g. via a \s-1DLL\s0) and you need a list of |
|
|
|
exported symbols, you can use the provided \fISymbol.*\fR files which list |
|
|
|
all public symbols, one per line: |
|
|
|
.PP |
|
|
@ -5064,7 +5076,7 @@ And a \fIev_cpp.C\fR implementation file that contains libev proper and is compi |
|
|
|
.Ve |
|
|
|
.SH "INTERACTION WITH OTHER PROGRAMS, LIBRARIES OR THE ENVIRONMENT" |
|
|
|
.IX Header "INTERACTION WITH OTHER PROGRAMS, LIBRARIES OR THE ENVIRONMENT" |
|
|
|
.SS "\s-1THREADS\s0 \s-1AND\s0 \s-1COROUTINES\s0" |
|
|
|
.SS "\s-1THREADS AND COROUTINES\s0" |
|
|
|
.IX Subsection "THREADS AND COROUTINES" |
|
|
|
\fI\s-1THREADS\s0\fR |
|
|
|
.IX Subsection "THREADS" |
|
|
@ -5120,7 +5132,7 @@ work in the default loop by registering the signal watcher with the |
|
|
|
default loop and triggering an \f(CW\*(C`ev_async\*(C'\fR watcher from the default loop |
|
|
|
watcher callback into the event loop interested in the signal. |
|
|
|
.PP |
|
|
|
See also \*(L"\s-1THREAD\s0 \s-1LOCKING\s0 \s-1EXAMPLE\s0\*(R". |
|
|
|
See also \*(L"\s-1THREAD LOCKING EXAMPLE\*(R"\s0. |
|
|
|
.PP |
|
|
|
\fI\s-1COROUTINES\s0\fR |
|
|
|
.IX Subsection "COROUTINES" |
|
|
@ -5135,7 +5147,7 @@ that you must not do this from \f(CW\*(C`ev_periodic\*(C'\fR reschedule callback |
|
|
|
Care has been taken to ensure that libev does not keep local state inside |
|
|
|
\&\f(CW\*(C`ev_run\*(C'\fR, and other calls do not usually allow for coroutine switches as |
|
|
|
they do not call any callbacks. |
|
|
|
.SS "\s-1COMPILER\s0 \s-1WARNINGS\s0" |
|
|
|
.SS "\s-1COMPILER WARNINGS\s0" |
|
|
|
.IX Subsection "COMPILER WARNINGS" |
|
|
|
Depending on your compiler and compiler settings, you might get no or a |
|
|
|
lot of warnings when compiling libev code. Some people are apparently |
|
|
@ -5197,7 +5209,7 @@ If you need, for some reason, empty reports from valgrind for your project |
|
|
|
I suggest using suppression lists. |
|
|
|
.SH "PORTABILITY NOTES" |
|
|
|
.IX Header "PORTABILITY NOTES" |
|
|
|
.SS "\s-1GNU/LINUX\s0 32 \s-1BIT\s0 \s-1LIMITATIONS\s0" |
|
|
|
.SS "\s-1GNU/LINUX 32 BIT LIMITATIONS\s0" |
|
|
|
.IX Subsection "GNU/LINUX 32 BIT LIMITATIONS" |
|
|
|
GNU/Linux is the only common platform that supports 64 bit file/large file |
|
|
|
interfaces but \fIdisables\fR them by default. |
|
|
@ -5206,13 +5218,13 @@ That means that libev compiled in the default environment doesn't support |
|
|
|
files larger than 2GiB or so, which mainly affects \f(CW\*(C`ev_stat\*(C'\fR watchers. |
|
|
|
.PP |
|
|
|
Unfortunately, many programs try to work around this GNU/Linux issue |
|
|
|
by enabling the large file \s-1API\s0, which makes them incompatible with the |
|
|
|
by enabling the large file \s-1API,\s0 which makes them incompatible with the |
|
|
|
standard libev compiled for their system. |
|
|
|
.PP |
|
|
|
Likewise, libev cannot enable the large file \s-1API\s0 itself as this would |
|
|
|
suddenly make it incompatible to the default compile time environment, |
|
|
|
i.e. all programs not using special compile switches. |
|
|
|
.SS "\s-1OS/X\s0 \s-1AND\s0 \s-1DARWIN\s0 \s-1BUGS\s0" |
|
|
|
.SS "\s-1OS/X AND DARWIN BUGS\s0" |
|
|
|
.IX Subsection "OS/X AND DARWIN BUGS" |
|
|
|
The whole thing is a bug if you ask me \- basically any system interface |
|
|
|
you touch is broken, whether it is locales, poll, kqueue or even the |
|
|
@ -5244,14 +5256,14 @@ a loop. |
|
|
|
.IX Subsection "select is buggy" |
|
|
|
.PP |
|
|
|
All that's left is \f(CW\*(C`select\*(C'\fR, and of course Apple found a way to fuck this |
|
|
|
one up as well: On \s-1OS/X\s0, \f(CW\*(C`select\*(C'\fR actively limits the number of file |
|
|
|
one up as well: On \s-1OS/X, \s0\f(CW\*(C`select\*(C'\fR actively limits the number of file |
|
|
|
descriptors you can pass in to 1024 \- your program suddenly crashes when |
|
|
|
you use more. |
|
|
|
.PP |
|
|
|
There is an undocumented \*(L"workaround\*(R" for this \- defining |
|
|
|
\&\f(CW\*(C`_DARWIN_UNLIMITED_SELECT\*(C'\fR, which libev tries to use, so select \fIshould\fR |
|
|
|
work on \s-1OS/X\s0. |
|
|
|
.SS "\s-1SOLARIS\s0 \s-1PROBLEMS\s0 \s-1AND\s0 \s-1WORKAROUNDS\s0" |
|
|
|
work on \s-1OS/X.\s0 |
|
|
|
.SS "\s-1SOLARIS PROBLEMS AND WORKAROUNDS\s0" |
|
|
|
.IX Subsection "SOLARIS PROBLEMS AND WORKAROUNDS" |
|
|
|
\fI\f(CI\*(C`errno\*(C'\fI reentrancy\fR |
|
|
|
.IX Subsection "errno reentrancy" |
|
|
@ -5278,13 +5290,13 @@ great. |
|
|
|
If you can't get it to work, you can try running the program by setting |
|
|
|
the environment variable \f(CW\*(C`LIBEV_FLAGS=3\*(C'\fR to only allow \f(CW\*(C`poll\*(C'\fR and |
|
|
|
\&\f(CW\*(C`select\*(C'\fR backends. |
|
|
|
.SS "\s-1AIX\s0 \s-1POLL\s0 \s-1BUG\s0" |
|
|
|
.SS "\s-1AIX POLL BUG\s0" |
|
|
|
.IX Subsection "AIX POLL BUG" |
|
|
|
\&\s-1AIX\s0 unfortunately has a broken \f(CW\*(C`poll.h\*(C'\fR header. Libev works around |
|
|
|
this by trying to avoid the poll backend altogether (i.e. it's not even |
|
|
|
compiled in), which normally isn't a big problem as \f(CW\*(C`select\*(C'\fR works fine |
|
|
|
with large bitsets on \s-1AIX\s0, and \s-1AIX\s0 is dead anyway. |
|
|
|
.SS "\s-1WIN32\s0 \s-1PLATFORM\s0 \s-1LIMITATIONS\s0 \s-1AND\s0 \s-1WORKAROUNDS\s0" |
|
|
|
with large bitsets on \s-1AIX,\s0 and \s-1AIX\s0 is dead anyway. |
|
|
|
.SS "\s-1WIN32 PLATFORM LIMITATIONS AND WORKAROUNDS\s0" |
|
|
|
.IX Subsection "WIN32 PLATFORM LIMITATIONS AND WORKAROUNDS" |
|
|
|
\fIGeneral issues\fR |
|
|
|
.IX Subsection "General issues" |
|
|
@ -5390,7 +5402,7 @@ runtime libraries. This might get you to about \f(CW512\fR or \f(CW2048\fR socke |
|
|
|
(depending on windows version and/or the phase of the moon). To get more, |
|
|
|
you need to wrap all I/O functions and provide your own fd management, but |
|
|
|
the cost of calling select (O(nX)) will likely make this unworkable. |
|
|
|
.SS "\s-1PORTABILITY\s0 \s-1REQUIREMENTS\s0" |
|
|
|
.SS "\s-1PORTABILITY REQUIREMENTS\s0" |
|
|
|
.IX Subsection "PORTABILITY REQUIREMENTS" |
|
|
|
In addition to a working ISO-C implementation and of course the |
|
|
|
backend-specific APIs, libev relies on a few additional extensions: |
|
|
@ -5398,7 +5410,7 @@ backend-specific APIs, libev relies on a few additional extensions: |
|
|
|
.el .IP "\f(CWvoid (*)(ev_watcher_type *, int revents)\fR must have compatible calling conventions regardless of \f(CWev_watcher_type *\fR." 4 |
|
|
|
.IX Item "void (*)(ev_watcher_type *, int revents) must have compatible calling conventions regardless of ev_watcher_type *." |
|
|
|
Libev assumes not only that all watcher pointers have the same internal |
|
|
|
structure (guaranteed by \s-1POSIX\s0 but not by \s-1ISO\s0 C for example), but it also |
|
|
|
structure (guaranteed by \s-1POSIX\s0 but not by \s-1ISO C\s0 for example), but it also |
|
|
|
assumes that the same (machine) code can be used to call any watcher |
|
|
|
callback: The watcher callbacks have different type signatures, but libev |
|
|
|
calls them using an \f(CW\*(C`ev_watcher *\*(C'\fR internally. |
|
|
@ -5429,7 +5441,7 @@ thread as well. |
|
|
|
.ie n .IP """long"" must be large enough for common memory allocation sizes" 4 |
|
|
|
.el .IP "\f(CWlong\fR must be large enough for common memory allocation sizes" 4 |
|
|
|
.IX Item "long must be large enough for common memory allocation sizes" |
|
|
|
To improve portability and simplify its \s-1API\s0, libev uses \f(CW\*(C`long\*(C'\fR internally |
|
|
|
To improve portability and simplify its \s-1API,\s0 libev uses \f(CW\*(C`long\*(C'\fR internally |
|
|
|
instead of \f(CW\*(C`size_t\*(C'\fR when allocating its data structures. On non-POSIX |
|
|
|
systems (Microsoft...) this might be unexpectedly low, but is still at |
|
|
|
least 31 bits everywhere, which is enough for hundreds of millions of |
|
|
@ -5441,9 +5453,9 @@ The type \f(CW\*(C`double\*(C'\fR is used to represent timestamps. It is require |
|
|
|
have at least 51 bits of mantissa (and 9 bits of exponent), which is |
|
|
|
good enough for at least into the year 4000 with millisecond accuracy |
|
|
|
(the design goal for libev). This requirement is overfulfilled by |
|
|
|
implementations using \s-1IEEE\s0 754, which is basically all existing ones. |
|
|
|
implementations using \s-1IEEE 754,\s0 which is basically all existing ones. |
|
|
|
.Sp |
|
|
|
With \s-1IEEE\s0 754 doubles, you get microsecond accuracy until at least the |
|
|
|
With \s-1IEEE 754\s0 doubles, you get microsecond accuracy until at least the |
|
|
|
year 2255 (and millisecond accuracy till the year 287396 \- by then, libev |
|
|
|
is either obsolete or somebody patched it to use \f(CW\*(C`long double\*(C'\fR or |
|
|
|
something like that, just kidding). |
|
|
@ -5515,7 +5527,7 @@ blocked. Checking for async and signal events involves iterating over all |
|
|
|
running async watchers or all signal numbers. |
|
|
|
.SH "PORTING FROM LIBEV 3.X TO 4.X" |
|
|
|
.IX Header "PORTING FROM LIBEV 3.X TO 4.X" |
|
|
|
The major version 4 introduced some incompatible changes to the \s-1API\s0. |
|
|
|
The major version 4 introduced some incompatible changes to the \s-1API.\s0 |
|
|
|
.PP |
|
|
|
At the moment, the \f(CW\*(C`ev.h\*(C'\fR header file provides compatibility definitions |
|
|
|
for all changes, so most programs should still compile. The compatibility |
|
|
@ -5525,7 +5537,7 @@ new \s-1API\s0 early than late. |
|
|
|
.el .IP "\f(CWEV_COMPAT3\fR backwards compatibility mechanism" 4 |
|
|
|
.IX Item "EV_COMPAT3 backwards compatibility mechanism" |
|
|
|
The backward compatibility mechanism can be controlled by |
|
|
|
\&\f(CW\*(C`EV_COMPAT3\*(C'\fR. See \*(L"\s-1PREPROCESSOR\s0 \s-1SYMBOLS/MACROS\s0\*(R" in the \*(L"\s-1EMBEDDING\s0\*(R" |
|
|
|
\&\f(CW\*(C`EV_COMPAT3\*(C'\fR. See \*(L"\s-1PREPROCESSOR SYMBOLS/MACROS\*(R"\s0 in the \*(L"\s-1EMBEDDING\*(R"\s0 |
|
|
|
section. |
|
|
|
.ie n .IP """ev_default_destroy"" and ""ev_default_fork"" have been removed" 4 |
|
|
|
.el .IP "\f(CWev_default_destroy\fR and \f(CWev_default_fork\fR have been removed" 4 |
|
|
@ -5575,7 +5587,7 @@ and work, but the library code will of course be larger. |
|
|
|
.IP "active" 4 |
|
|
|
.IX Item "active" |
|
|
|
A watcher is active as long as it has been started and not yet stopped. |
|
|
|
See \*(L"\s-1WATCHER\s0 \s-1STATES\s0\*(R" for details. |
|
|
|
See \*(L"\s-1WATCHER STATES\*(R"\s0 for details. |
|
|
|
.IP "application" 4 |
|
|
|
.IX Item "application" |
|
|
|
In this document, an application is whatever is using libev. |
|
|
@ -5612,7 +5624,7 @@ watchers and events. |
|
|
|
.IP "pending" 4 |
|
|
|
.IX Item "pending" |
|
|
|
A watcher is pending as soon as the corresponding event has been |
|
|
|
detected. See \*(L"\s-1WATCHER\s0 \s-1STATES\s0\*(R" for details. |
|
|
|
detected. See \*(L"\s-1WATCHER STATES\*(R"\s0 for details. |
|
|
|
.IP "real time" 4 |
|
|
|
.IX Item "real time" |
|
|
|
The physical time that is observed. It is apparently strictly monotonic :) |
|
|
|