Browse Source

Update libev to 4.22 (#854)

pull/855/merge
Xingyu Chen 8 years ago
committed by Max Lv
parent
commit
3f664546f8
9 changed files with 300 additions and 143 deletions
  1. 10
      libev/Changes
  2. 2
      libev/configure.ac
  3. 2
      libev/ev++.h
  4. 200
      libev/ev.3
  5. 211
      libev/ev.c
  6. 2
      libev/ev.h
  7. 7
      libev/ev.pod
  8. 4
      libev/ev_epoll.c
  9. 5
      libev/ev_win32.c

10
libev/Changes

@ -14,6 +14,16 @@ TODO: embed watchers need updating when fd changes
TODO: document portability requirements for atomic pointer access TODO: document portability requirements for atomic pointer access
TODO: document requirements for function pointers and calling conventions. TODO: document requirements for function pointers and calling conventions.
4.22 Sun Dec 20 22:11:50 CET 2015
- when epoll detects unremovable fds in the fd set, rebuild
only the epoll descriptor, not the signal pipe, to avoid
SIGPIPE in ev_async_send. This doesn't solve it on fork,
so document what needs to be done in ev_loop_fork
(analyzed by Benjamin Mahler).
- remove superfluous sys/timeb.h include on win32
(analyzed by Jason Madden).
- updated libecb.
4.20 Sat Jun 20 13:01:43 CEST 2015 4.20 Sat Jun 20 13:01:43 CEST 2015
- prefer noexcept over throw () with C++ 11. - prefer noexcept over throw () with C++ 11.
- update ecb.h due to incompatibilities with c11. - update ecb.h due to incompatibilities with c11.

2
libev/configure.ac

@ -5,7 +5,7 @@ orig_CFLAGS="$CFLAGS"
AC_CONFIG_SRCDIR([ev_epoll.c]) AC_CONFIG_SRCDIR([ev_epoll.c])
dnl also update ev.h! dnl also update ev.h!
AM_INIT_AUTOMAKE(libev,4.20)
AM_INIT_AUTOMAKE(libev,4.22)
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AM_MAINTAINER_MODE AM_MAINTAINER_MODE

2
libev/ev++.h

@ -575,7 +575,7 @@ namespace ev {
} }
#endif #endif
/* using a template here would require quite a bit more lines,
/* using a template here would require quite a few more lines,
* so a macro solution was chosen */ * so a macro solution was chosen */
#define EV_BEGIN_WATCHER(cppstem,cstem) \ #define EV_BEGIN_WATCHER(cppstem,cstem) \
\ \

200
libev/ev.3

@ -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: .\" Standard preamble:
.\" ======================================================================== .\" ========================================================================
@ -38,6 +38,8 @@
. ds PI \(*p . ds PI \(*p
. ds L" `` . ds L" ``
. ds R" '' . ds R" ''
. ds C`
. ds C'
'br\} 'br\}
.\" .\"
.\" Escape single quotes in literal strings from groff's Unicode transform. .\" 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 .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the .\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion. .\" 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). .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts. .\" Fear. Run. Save yourself. No user-serviceable parts.
@ -124,7 +133,7 @@
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "LIBEV 3" .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 .\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents. .\" way too many mistakes in technical documents.
.if n .ad l .if n .ad l
@ -136,7 +145,7 @@ libev \- a high performance full\-featured event loop written in C
.Vb 1 .Vb 1
\& #include <ev.h> \& #include <ev.h>
.Ve .Ve
.SS "\s-1EXAMPLE\s0 \s-1PROGRAM\s0"
.SS "\s-1EXAMPLE PROGRAM\s0"
.IX Subsection "EXAMPLE PROGRAM" .IX Subsection "EXAMPLE PROGRAM"
.Vb 2 .Vb 2
\& // a single header file is required \& // a single header file is required
@ -214,9 +223,9 @@ throughout this document.
.IX Header "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 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 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" .SH "ABOUT LIBEV"
.IX Header "ABOUT LIBEV" .IX Header "ABOUT LIBEV"
Libev is an event loop: you register interest in certain events (such as a 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 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 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. this argument.
.SS "\s-1TIME\s0 \s-1REPRESENTATION\s0"
.SS "\s-1TIME REPRESENTATION\s0"
.IX Subsection "TIME REPRESENTATION" .IX Subsection "TIME REPRESENTATION"
Libev represents time as a single floating point number, representing Libev represents time as a single floating point number, representing
the (fractional) number of seconds since the (\s-1POSIX\s0) epoch (in practice 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). \&\f(CW\*(C`pthread_atfork\*(C'\fR which is even faster).
.Sp .Sp
The big advantage of this flag is that you can forget about fork (and 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 .Sp
This flag setting cannot be overridden or specified in the \f(CW\*(C`LIBEV_FLAGS\*(C'\fR This flag setting cannot be overridden or specified in the \f(CW\*(C`LIBEV_FLAGS\*(C'\fR
environment variable. 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. This flag's behaviour will become the default in future versions of libev.
.ie n .IP """EVBACKEND_SELECT"" (value 1, portable select backend)" 4 .ie n .IP """EVBACKEND_SELECT"" (value 1, portable select backend)" 4
.el .IP "\f(CWEVBACKEND_SELECT\fR (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 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, 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 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). \&\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 .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 .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 And this is your standard \fIpoll\fR\|(2) backend. It's more complicated
than select, but handles sparse fds better and has no artificial 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 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. \&\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 .ie n .IP """EVBACKEND_EPOLL"" (value 4, Linux)" 4
.el .IP "\f(CWEVBACKEND_EPOLL\fR (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 Use the linux-specific \fIepoll\fR\|(7) interface (for both pre\- and post\-2.6.9
kernels). kernels).
.Sp .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. \&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
.ie n .IP """EVBACKEND_KQUEUE"" (value 8, most \s-1BSD\s0 clones)" 4 .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 .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 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 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 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 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 (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 (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 .Sp
This backend maps \f(CW\*(C`EV_READ\*(C'\fR into an \f(CW\*(C`EVFILT_READ\*(C'\fR kevent with 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, 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. immensely.
.ie n .IP """EVBACKEND_PORT"" (value 32, Solaris 10)" 4 .ie n .IP """EVBACKEND_PORT"" (value 32, Solaris 10)" 4
.el .IP "\f(CWEVBACKEND_PORT\fR (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, 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)). it's really slow, but it still scales very well (O(active_fds)).
.Sp .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 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. \&\f(CW\*(C`EVFLAG_FORKCHECK\*(C'\fR) in the child before resuming or calling \f(CW\*(C`ev_run\*(C'\fR.
.Sp .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 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 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 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 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 programs, though, as the fd could already be closed and reused for another
thing, so beware. thing, so beware.
.SS "\s-1GENERIC\s0 \s-1WATCHER\s0 \s-1FUNCTIONS\s0"
.SS "\s-1GENERIC WATCHER FUNCTIONS\s0"
.IX Subsection "GENERIC WATCHER FUNCTIONS" .IX Subsection "GENERIC WATCHER FUNCTIONS"
.ie n .IP """ev_init"" (ev_TYPE *watcher, callback)" 4 .ie n .IP """ev_init"" (ev_TYPE *watcher, callback)" 4
.el .IP "\f(CWev_init\fR (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 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 :). always \f(CW0\fR, which is supposed to not be too high and not be too low :).
.Sp .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. priorities.
.IP "ev_invoke (loop, ev_TYPE *watcher, int revents)" 4 .IP "ev_invoke (loop, ev_TYPE *watcher, int revents)" 4
.IX Item "ev_invoke (loop, ev_TYPE *watcher, int revents)" .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 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. functions that do not need a watcher.
.PP .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" .IX Subsection "WATCHER STATES"
There are various watcher states mentioned throughout this manual \- There are various watcher states mentioned throughout this manual \-
active, pending and so on. In this section these states and the rules to 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 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 you wish (but when you trash the memory block, you need to \f(CW\*(C`ev_TYPE_init\*(C'\fR
it again). it again).
.SS "\s-1WATCHER\s0 \s-1PRIORITY\s0 \s-1MODELS\s0"
.SS "\s-1WATCHER PRIORITY MODELS\s0"
.IX Subsection "WATCHER PRIORITY MODELS" .IX Subsection "WATCHER PRIORITY MODELS"
Many event loops support \fIwatcher priorities\fR, which are usually small Many event loops support \fIwatcher priorities\fR, which are usually small
integers that influence the ordering of event callback invocation 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 Since files are typically not-so-well supported by advanced notification
mechanism, libev tries hard to emulate \s-1POSIX\s0 behaviour with respect 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 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 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 (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 \&\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. it \*(L"just works\*(R" instead of freezing.
.PP .PP
So avoid file descriptors pointing to files when you know it (e.g. use 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 when you rarely read from a file instead of from a socket, and want to
reuse the same code path. reuse the same code path.
.PP .PP
@ -1796,17 +1808,17 @@ To support fork in your child processes, you have to call \f(CW\*(C`ev_loop_fork
.PP .PP
While not really specific to libev, it is easy to forget about \f(CW\*(C`SIGPIPE\*(C'\fR: 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 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. this is sensible behaviour, for daemons, this is usually undesirable.
.PP .PP
So when you encounter spurious, unexplained daemon exits, make sure you 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). somewhere, as that would have given you a big clue).
.PP .PP
\fIThe special problem of \fIaccept()\fIing when you can't\fR \fIThe special problem of \fIaccept()\fIing when you can't\fR
.IX Subsection "The special problem of accept()ing when you can't" .IX Subsection "The special problem of accept()ing when you can't"
.PP .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 found in post\-2004 Linux) have the peculiar behaviour of not removing a
connection from the pending queue in all error cases. connection from the pending queue in all error cases.
.PP .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 reschedule callback will be called with the watcher as first, and the
current time as second argument. current time as second argument.
.Sp .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 or make \s-1ANY\s0 other event loop modifications whatsoever, unless explicitly
allowed by documentation here\fR. allowed by documentation here\fR.
.Sp .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 will usually be called just before the callback will be triggered, but
might be called at other times, too. might be called at other times, too.
.Sp .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. equal to the passed \f(CI\*(C`now\*(C'\fI value\fR.
.Sp .Sp
This can be used to create very complex timers, such as a timer that 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. catch fork calls done by libraries (such as the libc) as well.
.PP .PP
In current versions of libev, the signal will not be blocked indefinitely 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 the window of opportunity for problems, it will not go away, as libev
\&\fIhas\fR to modify the signal mask, at least temporarily. \&\fIhas\fR to modify the signal mask, at least temporarily.
.PP .PP
@ -2622,7 +2634,7 @@ The signal the watcher watches out for.
\fIExamples\fR \fIExamples\fR
.IX Subsection "Examples" .IX Subsection "Examples"
.PP .PP
Example: Try to exit cleanly on \s-1SIGINT\s0.
Example: Try to exit cleanly on \s-1SIGINT.\s0
.PP .PP
.Vb 5 .Vb 5
\& static void \& 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 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 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 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. most noticeably displayed with ev_stat and large file support.
.PP .PP
The solution for this is to lobby your distribution maker to make large 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 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 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 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 this approach, effectively embedding \s-1EV\s0 as a client into the horrible
libglib event loop. libglib event loop.
.PP .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 a timeout and an io event at the same time \- you probably should give io
events precedence. events precedence.
.Sp .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 .Sp
.Vb 7 .Vb 7
\& static void stdin_ready (int revents, void *arg) \& 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 This section explains some common idioms that are not immediately
obvious. Note that examples are sprinkled over the whole manual, and this obvious. Note that examples are sprinkled over the whole manual, and this
section only contains stuff that wouldn't fit anywhere else. 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" .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 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 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 .PP
More interesting and less C\-conformant ways of casting your callback More interesting and less C\-conformant ways of casting your callback
function type instead have been omitted. 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" .IX Subsection "BUILDING YOUR OWN COMPOSITE WATCHERS"
Another common scenario is to use some data structure with multiple Another common scenario is to use some data structure with multiple
embedded watchers, in effect creating your own watcher that combines embedded watchers, in effect creating your own watcher that combines
@ -3757,7 +3769,7 @@ real programmers):
\& (((char *)w) \- offsetof (struct my_biggy, t2)); \& (((char *)w) \- offsetof (struct my_biggy, t2));
\& } \& }
.Ve .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" .IX Subsection "AVOIDING FINISHING BEFORE RETURNING"
Often you have structures like this in event-based programs: Often you have structures like this in event-based programs:
.PP .PP
@ -3800,7 +3812,7 @@ pushing it into the pending queue:
.PP .PP
This way, \f(CW\*(C`start_new_request\*(C'\fR can safely return before the callback is 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. 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" .IX Subsection "MODEL/NESTED EVENT LOOP INVOCATIONS AND EXIT CONDITIONS"
Often (especially in \s-1GUI\s0 toolkits) there are places where you have Often (especially in \s-1GUI\s0 toolkits) there are places where you have
\&\fImodal\fR interaction, which is most easily implemented by recursively \&\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 both
\& exit_main_loop = exit_nested_loop = 1; \& exit_main_loop = exit_nested_loop = 1;
.Ve .Ve
.SS "\s-1THREAD\s0 \s-1LOCKING\s0 \s-1EXAMPLE\s0"
.SS "\s-1THREAD LOCKING EXAMPLE\s0"
.IX Subsection "THREAD LOCKING EXAMPLE" .IX Subsection "THREAD LOCKING EXAMPLE"
Here is a fictitious example of how to run an event loop in a different 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 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 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 about the newly added timer. By waking up the loop it will pick up any new
watchers in the next event loop iteration. 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" .IX Subsection "THREADS, COROUTINES, CONTINUATIONS, QUEUES... INSTEAD OF CALLBACKS"
While the overhead of a callback that e.g. schedules a thread is small, it 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 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 switching to a coroutine, you push the watcher onto the queue and notify
any waiters. any waiters.
.PP .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: files, \fImy_ev.h\fR and \fImy_ev.c\fR that include the respective libev files:
.PP .PP
.Vb 4 .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 \&\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). and \f(CW\*(C`EV::Glib\*(C'\fR).
.Sp .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>. <http://software.schmorp.de/pkg/EV>.
.IP "Python" 4 .IP "Python" 4
.IX Item "Python" .IX Item "Python"
@ -4362,7 +4374,7 @@ makes rev work even on mingw.
.IP "Haskell" 4 .IP "Haskell" 4
.IX Item "Haskell" .IX Item "Haskell"
A haskell binding to libev is available at 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 .IP "D" 4
.IX Item "D" .IX Item "D"
Leandro Lucarella has written a D language binding (\fIev.d\fR) for libev, to 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 .IP "Ocaml" 4
.IX Item "Ocaml" .IX Item "Ocaml"
Erkki Seppala has written Ocaml bindings for libev, to be found at 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 .IP "Lua" 4
.IX Item "Lua" .IX Item "Lua"
Brian Maher has written a partial interface to libev for lua (at the 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 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 .IP "Javascript" 4
.IX Item "Javascript" .IX Item "Javascript"
Node.js (<http://nodejs.org>) uses libev as the underlying event library. 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 Depending on what features you need you need to include one or more sets of files
in your application. in your application.
.PP .PP
\fI\s-1CORE\s0 \s-1EVENT\s0 \s-1LOOP\s0\fR
\fI\s-1CORE EVENT LOOP\s0\fR
.IX Subsection "CORE EVENT LOOP" .IX Subsection "CORE EVENT LOOP"
.PP .PP
To include only the libev core (all the \f(CW\*(C`ev_*\*(C'\fR functions), with manual 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 .PP
This will automatically include \fIev.h\fR, too, and should be done in a 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 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 done by writing a wrapper around \fIev.h\fR that you can include instead and
where you can put other configuration options): where you can put other configuration options):
.PP .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 \&\fIev.c\fR includes the backend files directly when enabled, so you only need
to compile this single file. to compile this single file.
.PP .PP
\fI\s-1LIBEVENT\s0 \s-1COMPATIBILITY\s0 \s-1API\s0\fR
\fI\s-1LIBEVENT COMPATIBILITY API\s0\fR
.IX Subsection "LIBEVENT COMPATIBILITY API" .IX Subsection "LIBEVENT COMPATIBILITY API"
.PP .PP
To include the libevent compatibility \s-1API\s0, also include:
To include the libevent compatibility \s-1API,\s0 also include:
.PP .PP
.Vb 1 .Vb 1
\& #include "event.c" \& #include "event.c"
@ -4536,7 +4548,7 @@ in the file including \fIev.c\fR, and:
\& #include "event.h" \& #include "event.h"
.Ve .Ve
.PP .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 .PP
You need the following additional files for this: You need the following additional files for this:
.PP .PP
@ -4545,7 +4557,7 @@ You need the following additional files for this:
\& event.c \& event.c
.Ve .Ve
.PP .PP
\fI\s-1AUTOCONF\s0 \s-1SUPPORT\s0\fR
\fI\s-1AUTOCONF SUPPORT\s0\fR
.IX Subsection "AUTOCONF SUPPORT" .IX Subsection "AUTOCONF SUPPORT"
.PP .PP
Instead of using \f(CW\*(C`EV_STANDALONE=1\*(C'\fR and providing your configuration in 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 .Vb 1
\& libev.m4 \& libev.m4
.Ve .Ve
.SS "\s-1PREPROCESSOR\s0 \s-1SYMBOLS/MACROS\s0"
.SS "\s-1PREPROCESSOR SYMBOLS/MACROS\s0"
.IX Subsection "PREPROCESSOR SYMBOLS/MACROS" .IX Subsection "PREPROCESSOR SYMBOLS/MACROS"
Libev can be configured via a variety of preprocessor symbols you have to 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 define before including (or compiling) any of its files. The default in
the absence of autoconf is documented for every option. the absence of autoconf is documented for every option.
.PP .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 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 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 users of libev and the libev code itself must be compiled with compatible
settings. settings.
.IP "\s-1EV_COMPAT3\s0 (h)" 4
.IP "\s-1EV_COMPAT3 \s0(h)" 4
.IX Item "EV_COMPAT3 (h)" .IX Item "EV_COMPAT3 (h)"
Backwards compatibility is a major concern for libev. This is why this Backwards compatibility is a major concern for libev. This is why this
release of libev comes with wrappers for the functions and symbols that 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, 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 and in some even more future version the compatibility code will be
removed completely. removed completely.
.IP "\s-1EV_STANDALONE\s0 (h)" 4
.IP "\s-1EV_STANDALONE \s0(h)" 4
.IX Item "EV_STANDALONE (h)" .IX Item "EV_STANDALONE (h)"
Must always be \f(CW1\fR if you do not use autoconf configuration, which 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 keeps libev from including \fIconfig.h\fR, and it also defines dummy
@ -4753,21 +4765,21 @@ watchers.
.Sp .Sp
In the absence of this define, libev will use \f(CW\*(C`sig_atomic_t volatile\*(C'\fR 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. (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)" .IX Item "EV_H (h)"
The name of the \fIev.h\fR header file used to include it. The default if 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 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. 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)" .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 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 \&\fIev.c\fR's idea of where to find the \fIconfig.h\fR file, similarly to
\&\f(CW\*(C`EV_H\*(C'\fR, above. \&\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)" .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 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. 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)" .IX Item "EV_PROTOTYPES (h)"
If defined to be \f(CW0\fR, then \fIev.h\fR will not define any function 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 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. fine.
.Sp .Sp
If your embedding application does not need any priorities, defining these 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." .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 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 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 *self; /* contains this struct */ \e
\& SV *cb_sv, *fh /* note no trailing ";" */ \& SV *cb_sv, *fh /* note no trailing ";" */
.Ve .Ve
.IP "\s-1EV_CB_DECLARE\s0 (type)" 4
.IP "\s-1EV_CB_DECLARE \s0(type)" 4
.IX Item "EV_CB_DECLARE (type)" .IX Item "EV_CB_DECLARE (type)"
.PD 0 .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)" .IX Item "EV_CB_INVOKE (watcher, revents)"
.IP "ev_set_cb (ev, cb)" 4 .IP "ev_set_cb (ev, cb)" 4
.IX Item "ev_set_cb (ev, cb)" .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 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 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+. 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" .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 exported symbols, you can use the provided \fISymbol.*\fR files which list
all public symbols, one per line: all public symbols, one per line:
.PP .PP
@ -5064,7 +5076,7 @@ And a \fIev_cpp.C\fR implementation file that contains libev proper and is compi
.Ve .Ve
.SH "INTERACTION WITH OTHER PROGRAMS, LIBRARIES OR THE ENVIRONMENT" .SH "INTERACTION WITH OTHER PROGRAMS, LIBRARIES OR THE ENVIRONMENT"
.IX Header "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" .IX Subsection "THREADS AND COROUTINES"
\fI\s-1THREADS\s0\fR \fI\s-1THREADS\s0\fR
.IX Subsection "THREADS" .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 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. watcher callback into the event loop interested in the signal.
.PP .PP
See also \*(L"\s-1THREAD\s0 \s-1LOCKING\s0 \s-1EXAMPLE\s0\*(R".
See also \*(L"\s-1THREAD LOCKING EXAMPLE\*(R"\s0.
.PP .PP
\fI\s-1COROUTINES\s0\fR \fI\s-1COROUTINES\s0\fR
.IX Subsection "COROUTINES" .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 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 \&\f(CW\*(C`ev_run\*(C'\fR, and other calls do not usually allow for coroutine switches as
they do not call any callbacks. they do not call any callbacks.
.SS "\s-1COMPILER\s0 \s-1WARNINGS\s0"
.SS "\s-1COMPILER WARNINGS\s0"
.IX Subsection "COMPILER WARNINGS" .IX Subsection "COMPILER WARNINGS"
Depending on your compiler and compiler settings, you might get no or a Depending on your compiler and compiler settings, you might get no or a
lot of warnings when compiling libev code. Some people are apparently 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. I suggest using suppression lists.
.SH "PORTABILITY NOTES" .SH "PORTABILITY NOTES"
.IX Header "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" .IX Subsection "GNU/LINUX 32 BIT LIMITATIONS"
GNU/Linux is the only common platform that supports 64 bit file/large file GNU/Linux is the only common platform that supports 64 bit file/large file
interfaces but \fIdisables\fR them by default. 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. files larger than 2GiB or so, which mainly affects \f(CW\*(C`ev_stat\*(C'\fR watchers.
.PP .PP
Unfortunately, many programs try to work around this GNU/Linux issue 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. standard libev compiled for their system.
.PP .PP
Likewise, libev cannot enable the large file \s-1API\s0 itself as this would Likewise, libev cannot enable the large file \s-1API\s0 itself as this would
suddenly make it incompatible to the default compile time environment, suddenly make it incompatible to the default compile time environment,
i.e. all programs not using special compile switches. 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" .IX Subsection "OS/X AND DARWIN BUGS"
The whole thing is a bug if you ask me \- basically any system interface 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 you touch is broken, whether it is locales, poll, kqueue or even the
@ -5244,14 +5256,14 @@ a loop.
.IX Subsection "select is buggy" .IX Subsection "select is buggy"
.PP .PP
All that's left is \f(CW\*(C`select\*(C'\fR, and of course Apple found a way to fuck this 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 descriptors you can pass in to 1024 \- your program suddenly crashes when
you use more. you use more.
.PP .PP
There is an undocumented \*(L"workaround\*(R" for this \- defining 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 \&\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" .IX Subsection "SOLARIS PROBLEMS AND WORKAROUNDS"
\fI\f(CI\*(C`errno\*(C'\fI reentrancy\fR \fI\f(CI\*(C`errno\*(C'\fI reentrancy\fR
.IX Subsection "errno reentrancy" .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 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 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. \&\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" .IX Subsection "AIX POLL BUG"
\&\s-1AIX\s0 unfortunately has a broken \f(CW\*(C`poll.h\*(C'\fR header. Libev works around \&\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 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 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" .IX Subsection "WIN32 PLATFORM LIMITATIONS AND WORKAROUNDS"
\fIGeneral issues\fR \fIGeneral issues\fR
.IX Subsection "General issues" .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, (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 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. 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" .IX Subsection "PORTABILITY REQUIREMENTS"
In addition to a working ISO-C implementation and of course the In addition to a working ISO-C implementation and of course the
backend-specific APIs, libev relies on a few additional extensions: 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 .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 *." .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 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 assumes that the same (machine) code can be used to call any watcher
callback: The watcher callbacks have different type signatures, but libev callback: The watcher callbacks have different type signatures, but libev
calls them using an \f(CW\*(C`ev_watcher *\*(C'\fR internally. 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 .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 .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" .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 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 systems (Microsoft...) this might be unexpectedly low, but is still at
least 31 bits everywhere, which is enough for hundreds of millions of 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 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 good enough for at least into the year 4000 with millisecond accuracy
(the design goal for libev). This requirement is overfulfilled by (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 .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 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 is either obsolete or somebody patched it to use \f(CW\*(C`long double\*(C'\fR or
something like that, just kidding). 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. running async watchers or all signal numbers.
.SH "PORTING FROM LIBEV 3.X TO 4.X" .SH "PORTING FROM LIBEV 3.X TO 4.X"
.IX Header "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 .PP
At the moment, the \f(CW\*(C`ev.h\*(C'\fR header file provides compatibility definitions 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 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 .el .IP "\f(CWEV_COMPAT3\fR backwards compatibility mechanism" 4
.IX Item "EV_COMPAT3 backwards compatibility mechanism" .IX Item "EV_COMPAT3 backwards compatibility mechanism"
The backward compatibility mechanism can be controlled by 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. section.
.ie n .IP """ev_default_destroy"" and ""ev_default_fork"" have been removed" 4 .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 .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 .IP "active" 4
.IX Item "active" .IX Item "active"
A watcher is active as long as it has been started and not yet stopped. 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 .IP "application" 4
.IX Item "application" .IX Item "application"
In this document, an application is whatever is using libev. In this document, an application is whatever is using libev.
@ -5612,7 +5624,7 @@ watchers and events.
.IP "pending" 4 .IP "pending" 4
.IX Item "pending" .IX Item "pending"
A watcher is pending as soon as the corresponding event has been 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 .IP "real time" 4
.IX Item "real time" .IX Item "real time"
The physical time that is observed. It is apparently strictly monotonic :) The physical time that is observed. It is apparently strictly monotonic :)

211
libev/ev.c

@ -534,7 +534,7 @@ struct signalfd_siginfo
#define ECB_H #define ECB_H
/* 16 bits major, 16 bits minor */ /* 16 bits major, 16 bits minor */
#define ECB_VERSION 0x00010004
#define ECB_VERSION 0x00010005
#ifdef _WIN32 #ifdef _WIN32
typedef signed char int8_t; typedef signed char int8_t;
@ -561,7 +561,7 @@ struct signalfd_siginfo
#endif #endif
#else #else
#include <inttypes.h> #include <inttypes.h>
#if UINTMAX_MAX > 0xffffffffU
#if (defined INTPTR_MAX ? INTPTR_MAX : ULONG_MAX) > 0xffffffffU
#define ECB_PTRSIZE 8 #define ECB_PTRSIZE 8
#else #else
#define ECB_PTRSIZE 4 #define ECB_PTRSIZE 4
@ -649,6 +649,10 @@ struct signalfd_siginfo
#include <builtins.h> #include <builtins.h>
#endif #endif
#if 1400 <= _MSC_VER
#include <intrin.h> /* fence functions _ReadBarrier, also bit search functions _BitScanReverse */
#endif
#ifndef ECB_MEMORY_FENCE #ifndef ECB_MEMORY_FENCE
#if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110 #if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
#if __i386 || __i386__ #if __i386 || __i386__
@ -661,15 +665,23 @@ struct signalfd_siginfo
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("") #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
#elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ #elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory") #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
#elif defined __ARM_ARCH_2__ \
|| defined __ARM_ARCH_3__ || defined __ARM_ARCH_3M__ \
|| defined __ARM_ARCH_4__ || defined __ARM_ARCH_4T__ \
|| defined __ARM_ARCH_5__ || defined __ARM_ARCH_5E__ \
|| defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__ \
|| defined __ARM_ARCH_5TEJ__
/* should not need any, unless running old code on newer cpu - arm doesn't support that */
#elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ \ #elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ \
|| defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6ZK__
|| defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6ZK__ \
|| defined __ARM_ARCH_6T2__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mcr p15,0,%0,c7,c10,5" : : "r" (0) : "memory") #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mcr p15,0,%0,c7,c10,5" : : "r" (0) : "memory")
#elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \ #elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \
|| defined __ARM_ARCH_7M__ || defined __ARM_ARCH_7R__
|| defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory") #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory")
#elif __aarch64__ #elif __aarch64__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb ish" : : : "memory") #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb ish" : : : "memory")
#elif (__sparc || __sparc__) && !__sparcv8
#elif (__sparc || __sparc__) && !(__sparc_v8__ || defined __sparcv8)
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory") #define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory")
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory") #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory")
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore") #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore")
@ -917,6 +929,11 @@ typedef int ecb_bool;
ecb_function_ ecb_const int ecb_function_ ecb_const int
ecb_ctz32 (uint32_t x) ecb_ctz32 (uint32_t x)
{ {
#if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM)
unsigned long r;
_BitScanForward (&r, x);
return (int)r;
#else
int r = 0; int r = 0;
x &= ~x + 1; /* this isolates the lowest bit */ x &= ~x + 1; /* this isolates the lowest bit */
@ -936,14 +953,21 @@ typedef int ecb_bool;
#endif #endif
return r; return r;
#endif
} }
ecb_function_ ecb_const int ecb_ctz64 (uint64_t x); ecb_function_ ecb_const int ecb_ctz64 (uint64_t x);
ecb_function_ ecb_const int ecb_function_ ecb_const int
ecb_ctz64 (uint64_t x) ecb_ctz64 (uint64_t x)
{ {
int shift = x & 0xffffffffU ? 0 : 32;
#if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM)
unsigned long r;
_BitScanForward64 (&r, x);
return (int)r;
#else
int shift = x & 0xffffffff ? 0 : 32;
return ecb_ctz32 (x >> shift) + shift; return ecb_ctz32 (x >> shift) + shift;
#endif
} }
ecb_function_ ecb_const int ecb_popcount32 (uint32_t x); ecb_function_ ecb_const int ecb_popcount32 (uint32_t x);
@ -961,6 +985,11 @@ typedef int ecb_bool;
ecb_function_ ecb_const int ecb_ld32 (uint32_t x); ecb_function_ ecb_const int ecb_ld32 (uint32_t x);
ecb_function_ ecb_const int ecb_ld32 (uint32_t x) ecb_function_ ecb_const int ecb_ld32 (uint32_t x)
{ {
#if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM)
unsigned long r;
_BitScanReverse (&r, x);
return (int)r;
#else
int r = 0; int r = 0;
if (x >> 16) { x >>= 16; r += 16; } if (x >> 16) { x >>= 16; r += 16; }
@ -970,16 +999,23 @@ typedef int ecb_bool;
if (x >> 1) { r += 1; } if (x >> 1) { r += 1; }
return r; return r;
#endif
} }
ecb_function_ ecb_const int ecb_ld64 (uint64_t x); ecb_function_ ecb_const int ecb_ld64 (uint64_t x);
ecb_function_ ecb_const int ecb_ld64 (uint64_t x) ecb_function_ ecb_const int ecb_ld64 (uint64_t x)
{ {
#if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM)
unsigned long r;
_BitScanReverse64 (&r, x);
return (int)r;
#else
int r = 0; int r = 0;
if (x >> 32) { x >>= 32; r += 32; } if (x >> 32) { x >>= 32; r += 32; }
return r + ecb_ld32 (x); return r + ecb_ld32 (x);
#endif
} }
#endif #endif
@ -1092,8 +1128,8 @@ ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { retu
/* try to tell the compiler that some condition is definitely true */ /* try to tell the compiler that some condition is definitely true */
#define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0 #define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0
ecb_inline ecb_const unsigned char ecb_byteorder_helper (void);
ecb_inline ecb_const unsigned char
ecb_inline ecb_const uint32_t ecb_byteorder_helper (void);
ecb_inline ecb_const uint32_t
ecb_byteorder_helper (void) ecb_byteorder_helper (void)
{ {
/* the union code still generates code under pressure in gcc, */ /* the union code still generates code under pressure in gcc, */
@ -1102,26 +1138,28 @@ ecb_byteorder_helper (void)
/* the reason why we have this horrible preprocessor mess */ /* the reason why we have this horrible preprocessor mess */
/* is to avoid it in all cases, at least on common architectures */ /* is to avoid it in all cases, at least on common architectures */
/* or when using a recent enough gcc version (>= 4.6) */ /* or when using a recent enough gcc version (>= 4.6) */
#if ((__i386 || __i386__) && !__VOS__) || _M_IX86 || ECB_GCC_AMD64 || ECB_MSVC_AMD64
return 0x44;
#elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
return 0x44;
#elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
return 0x11;
#if (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
|| ((__i386 || __i386__ || _M_IX86 || ECB_GCC_AMD64 || ECB_MSVC_AMD64) && !__VOS__)
#define ECB_LITTLE_ENDIAN 1
return 0x44332211;
#elif (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \
|| ((__AARCH64EB__ || __MIPSEB__ || __ARMEB__) && !__VOS__)
#define ECB_BIG_ENDIAN 1
return 0x11223344;
#else #else
union union
{ {
uint32_t i;
uint8_t c;
} u = { 0x11223344 };
return u.c;
uint8_t c[4];
uint32_t u;
} u = { 0x11, 0x22, 0x33, 0x44 };
return u.u;
#endif #endif
} }
ecb_inline ecb_const ecb_bool ecb_big_endian (void); ecb_inline ecb_const ecb_bool ecb_big_endian (void);
ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; }
ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11223344; }
ecb_inline ecb_const ecb_bool ecb_little_endian (void); ecb_inline ecb_const ecb_bool ecb_little_endian (void);
ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; }
ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44332211; }
#if ECB_GCC_VERSION(3,0) || ECB_C99 #if ECB_GCC_VERSION(3,0) || ECB_C99
#define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0)) #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))
@ -1156,6 +1194,102 @@ ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_he
#define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) #define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
#endif #endif
ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x);
ecb_function_ ecb_const uint32_t
ecb_binary16_to_binary32 (uint32_t x)
{
unsigned int s = (x & 0x8000) << (31 - 15);
int e = (x >> 10) & 0x001f;
unsigned int m = x & 0x03ff;
if (ecb_expect_false (e == 31))
/* infinity or NaN */
e = 255 - (127 - 15);
else if (ecb_expect_false (!e))
{
if (ecb_expect_true (!m))
/* zero, handled by code below by forcing e to 0 */
e = 0 - (127 - 15);
else
{
/* subnormal, renormalise */
unsigned int s = 10 - ecb_ld32 (m);
m = (m << s) & 0x3ff; /* mask implicit bit */
e -= s - 1;
}
}
/* e and m now are normalised, or zero, (or inf or nan) */
e += 127 - 15;
return s | (e << 23) | (m << (23 - 10));
}
ecb_function_ ecb_const uint16_t ecb_binary32_to_binary16 (uint32_t x);
ecb_function_ ecb_const uint16_t
ecb_binary32_to_binary16 (uint32_t x)
{
unsigned int s = (x >> 16) & 0x00008000; /* sign bit, the easy part */
unsigned int e = ((x >> 23) & 0x000000ff) - (127 - 15); /* the desired exponent */
unsigned int m = x & 0x007fffff;
x &= 0x7fffffff;
/* if it's within range of binary16 normals, use fast path */
if (ecb_expect_true (0x38800000 <= x && x <= 0x477fefff))
{
/* mantissa round-to-even */
m += 0x00000fff + ((m >> (23 - 10)) & 1);
/* handle overflow */
if (ecb_expect_false (m >= 0x00800000))
{
m >>= 1;
e += 1;
}
return s | (e << 10) | (m >> (23 - 10));
}
/* handle large numbers and infinity */
if (ecb_expect_true (0x477fefff < x && x <= 0x7f800000))
return s | 0x7c00;
/* handle zero, subnormals and small numbers */
if (ecb_expect_true (x < 0x38800000))
{
/* zero */
if (ecb_expect_true (!x))
return s;
/* handle subnormals */
/* too small, will be zero */
if (e < (14 - 24)) /* might not be sharp, but is good enough */
return s;
m |= 0x00800000; /* make implicit bit explicit */
/* very tricky - we need to round to the nearest e (+10) bit value */
{
unsigned int bits = 14 - e;
unsigned int half = (1 << (bits - 1)) - 1;
unsigned int even = (m >> bits) & 1;
/* if this overflows, we will end up with a normalised number */
m = (m + half + even) >> bits;
}
return s | m;
}
/* handle NaNs, preserve leftmost nan bits, but make sure we don't turn them into infinities */
m >>= 13;
return s | 0x7c00 | m | !m;
}
/*******************************************************************************/ /*******************************************************************************/
/* floating point stuff, can be disabled by defining ECB_NO_LIBM */ /* floating point stuff, can be disabled by defining ECB_NO_LIBM */
@ -1207,23 +1341,6 @@ ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_he
#define ecb_frexpf(x,e) (float) frexp ((double) (x), (e)) #define ecb_frexpf(x,e) (float) frexp ((double) (x), (e))
#endif #endif
/* converts an ieee half/binary16 to a float */
ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x);
ecb_function_ ecb_const float
ecb_binary16_to_float (uint16_t x)
{
int e = (x >> 10) & 0x1f;
int m = x & 0x3ff;
float r;
if (!e ) r = ecb_ldexpf (m , -24);
else if (e != 31) r = ecb_ldexpf (m + 0x400, e - 25);
else if (m ) r = ECB_NAN;
else r = ECB_INFINITY;
return x & 0x8000 ? -r : r;
}
/* convert a float to ieee single/binary32 */ /* convert a float to ieee single/binary32 */
ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x); ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x);
ecb_function_ ecb_const uint32_t ecb_function_ ecb_const uint32_t
@ -1364,6 +1481,22 @@ ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_he
return r; return r;
} }
/* convert a float to ieee half/binary16 */
ecb_function_ ecb_const uint16_t ecb_float_to_binary16 (float x);
ecb_function_ ecb_const uint16_t
ecb_float_to_binary16 (float x)
{
return ecb_binary32_to_binary16 (ecb_float_to_binary32 (x));
}
/* convert an ieee half/binary16 to float */
ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x);
ecb_function_ ecb_const float
ecb_binary16_to_float (uint16_t x)
{
return ecb_binary32_to_float (ecb_binary16_to_binary32 (x));
}
#endif #endif
#endif #endif
@ -2603,7 +2736,7 @@ ev_recommended_backends (void) EV_THROW
{ {
unsigned int flags = ev_supported_backends (); unsigned int flags = ev_supported_backends ();
#if !defined(__NetBSD__) && !defined(__FreeBSD__)
#ifndef __NetBSD__
/* kqueue is borked on everything but netbsd apparently */ /* kqueue is borked on everything but netbsd apparently */
/* it usually doesn't work correctly on anything but sockets and pipes */ /* it usually doesn't work correctly on anything but sockets and pipes */
flags &= ~EVBACKEND_KQUEUE; flags &= ~EVBACKEND_KQUEUE;
@ -2918,7 +3051,7 @@ loop_fork (EV_P)
#endif #endif
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
if (ev_is_active (&pipe_w))
if (ev_is_active (&pipe_w) && postfork != 2)
{ {
/* pipe_write_wanted must be false now, so modifying fd vars should be safe */ /* pipe_write_wanted must be false now, so modifying fd vars should be safe */

2
libev/ev.h

@ -211,7 +211,7 @@ struct ev_loop;
/*****************************************************************************/ /*****************************************************************************/
#define EV_VERSION_MAJOR 4 #define EV_VERSION_MAJOR 4
#define EV_VERSION_MINOR 20
#define EV_VERSION_MINOR 22
/* eventmask, revents, events... */ /* eventmask, revents, events... */
enum { enum {

7
libev/ev.pod

@ -418,8 +418,8 @@ without a system call and thus I<very> fast, but my GNU/Linux system also has
C<pthread_atfork> which is even faster). C<pthread_atfork> which is even faster).
The big advantage of this flag is that you can forget about fork (and 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 C<SIGPIPE>) when you use this flag.
This flag setting cannot be overridden or specified in the C<LIBEV_FLAGS> This flag setting cannot be overridden or specified in the C<LIBEV_FLAGS>
environment variable. environment variable.
@ -691,6 +691,9 @@ watchers (except inside an C<ev_prepare> callback), but it makes most
sense after forking, in the child process. You I<must> call it (or use sense after forking, in the child process. You I<must> call it (or use
C<EVFLAG_FORKCHECK>) in the child before resuming or calling C<ev_run>. C<EVFLAG_FORKCHECK>) in the child before resuming or calling C<ev_run>.
In addition, if you want to reuse a loop (via this function or
C<EVFLAG_FORKCHECK>), you I<also> have to ignore C<SIGPIPE>.
Again, you I<have> to call it on I<any> loop that you want to re-use after Again, you I<have> to call it on I<any> loop that you want to re-use after
a fork, I<even if you do not plan to use the loop in the parent>. This is a fork, I<even if you do not plan to use the loop in the parent>. This is
because some kernel interfaces *cough* I<kqueue> *cough* do funny things because some kernel interfaces *cough* I<kqueue> *cough* do funny things

4
libev/ev_epoll.c

@ -179,7 +179,7 @@ epoll_poll (EV_P_ ev_tstamp timeout)
if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32))) if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32)))
{ {
/* recreate kernel state */ /* recreate kernel state */
postfork = 1;
postfork |= 2;
continue; continue;
} }
@ -203,7 +203,7 @@ epoll_poll (EV_P_ ev_tstamp timeout)
/* which is fortunately easy to do for us. */ /* which is fortunately easy to do for us. */
if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev))
{ {
postfork = 1; /* an error occurred, recreate kernel state */
postfork |= 2; /* an error occurred, recreate kernel state */
continue; continue;
} }
} }

5
libev/ev_win32.c

@ -39,9 +39,6 @@
#ifdef _WIN32 #ifdef _WIN32
/* timeb.h is actually xsi legacy functionality */
#include <sys/timeb.h>
/* note: the comment below could not be substantiated, but what would I care */ /* note: the comment below could not be substantiated, but what would I care */
/* MSDN says this is required to handle SIGFPE */ /* MSDN says this is required to handle SIGFPE */
/* my wild guess would be that using something floating-pointy is required */ /* my wild guess would be that using something floating-pointy is required */
@ -91,6 +88,8 @@ ev_pipe (int filedes [2])
if (connect (sock [0], (struct sockaddr *)&addr, addr_size)) if (connect (sock [0], (struct sockaddr *)&addr, addr_size))
goto fail; goto fail;
/* TODO: returns INVALID_SOCKET on winsock accept, not < 0. fix it */
/* when convenient, probably by just removing error checking altogether? */
if ((sock [1] = accept (listener, 0, 0)) < 0) if ((sock [1] = accept (listener, 0, 0)) < 0)
goto fail; goto fail;

Loading…
Cancel
Save