diff --git a/third_party/libev/CVS/Entries b/third_party/libev/CVS/Entries index bf8f5ab771fbd0e6956912fea9436c1ea2070122..3c85411935a1e377b9c97e38dccedc5ed65617dd 100644 --- a/third_party/libev/CVS/Entries +++ b/third_party/libev/CVS/Entries @@ -1,31 +1,31 @@ -/Changes/1.279/Mon Sep 3 19:51:13 2012// -/LICENSE/1.10/Thu Aug 23 21:30:38 2012// -/Makefile.am/1.9/Thu Aug 23 21:30:38 2012// -/README/1.21/Thu Aug 23 21:30:38 2012// -/README.embed/1.29/Thu Aug 23 21:30:38 2012// -/Symbols.ev/1.14/Thu Aug 23 21:30:38 2012// -/Symbols.event/1.4/Mon Sep 3 19:51:13 2012// -/autogen.sh/1.3/Thu Aug 23 21:30:38 2012// -/configure.ac/1.34/Thu Aug 23 21:30:38 2012// -/ev++.h/1.61/Mon Sep 3 19:51:13 2012// -/ev_epoll.c/1.67/Mon Sep 3 19:51:13 2012// -/ev_kqueue.c/1.54/Thu Aug 23 21:30:38 2012// -/ev_poll.c/1.39/Thu Aug 23 21:30:38 2012// -/ev_port.c/1.28/Thu Aug 23 21:30:38 2012// -/ev_select.c/1.55/Thu Aug 23 21:30:38 2012// -/ev_vars.h/1.53/Mon Sep 3 19:51:13 2012// -/ev_win32.c/1.15/Thu Aug 23 21:30:38 2012// -/ev_wrap.h/1.37/Mon Sep 3 19:51:13 2012// -/event.c/1.52/Thu Aug 23 21:30:38 2012// -/event.h/1.26/Thu Aug 23 21:30:38 2012// -/event_compat.h/1.8/Thu Aug 23 21:30:38 2012// -/import_libevent/1.29/Thu Aug 23 21:30:38 2012// -/libev.m4/1.15/Thu Aug 23 21:30:38 2012// -/update_ev_c/1.2/Thu Aug 23 21:30:38 2012// -/update_ev_wrap/1.6/Mon Sep 3 19:51:13 2012// -/update_symbols/1.1/Thu Aug 23 21:30:38 2012// -/ev.3/1.95/Mon Sep 3 19:53:02 2012// -/ev.c/1.448/Mon Sep 3 19:53:02 2012// -/ev.h/1.169/Mon Sep 3 19:53:02 2012// -/ev.pod/1.421/Mon Sep 3 19:53:02 2012// +/Makefile.am/1.9/Mon Aug 17 17:43:15 2015// +/README/1.21/Mon Aug 17 17:43:15 2015// +/README.embed/1.29/Mon Aug 17 17:43:15 2015// +/Symbols.ev/1.14/Mon Aug 17 17:43:15 2015// +/Symbols.event/1.4/Mon Aug 17 17:43:15 2015// +/autogen.sh/1.3/Mon Aug 17 17:43:15 2015// +/ev_poll.c/1.39/Mon Aug 17 17:43:15 2015// +/ev_port.c/1.28/Mon Aug 17 17:43:15 2015// +/ev_select.c/1.55/Mon Aug 17 17:43:15 2015// +/event.c/1.52/Mon Aug 17 17:43:15 2015// +/event.h/1.26/Mon Aug 17 17:43:15 2015// +/event_compat.h/1.8/Mon Aug 17 17:43:15 2015// +/import_libevent/1.29/Mon Aug 17 17:43:15 2015// +/update_ev_c/1.2/Mon Aug 17 17:43:15 2015// +/update_ev_wrap/1.6/Mon Aug 17 17:43:15 2015// +/update_symbols/1.1/Mon Aug 17 17:43:15 2015// +/Changes/1.307/Sun Oct 4 10:12:28 2015// +/LICENSE/1.11/Sun Oct 4 10:12:28 2015// +/configure.ac/1.40/Sun Oct 4 10:12:28 2015// +/ev++.h/1.62/Sun Oct 4 10:12:28 2015// +/ev.3/1.103/Sun Oct 4 10:12:28 2015// +/ev.c/1.477/Sun Oct 4 10:12:28 2015// +/ev.h/1.183/Sun Oct 4 10:12:28 2015// +/ev.pod/1.435/Sun Oct 4 10:12:28 2015// +/ev_epoll.c/1.68/Sun Oct 4 10:12:28 2015// +/ev_kqueue.c/1.55/Sun Oct 4 10:12:28 2015// +/ev_vars.h/1.58/Sun Oct 4 10:12:28 2015// +/ev_win32.c/1.16/Sun Oct 4 10:12:28 2015// +/ev_wrap.h/1.38/Sun Oct 4 10:12:28 2015// +/libev.m4/1.16/Sun Oct 4 10:12:28 2015// D diff --git a/third_party/libev/Changes b/third_party/libev/Changes index 54c16405defeae87ddd41bb4a47ed5d78e2d68ae..4f23954ff58ca3b62f2287909a6caa8f7207e0e9 100644 --- a/third_party/libev/Changes +++ b/third_party/libev/Changes @@ -6,11 +6,44 @@ TODO: faq, process a thing in each iteration TODO: dbeugging tips, ev_verify, ev_init twice TODO: ev_break for immediate exit (EVBREAK_NOW?) TODO: ev_feed_child_event - TODO: document the special problem of signals around fork. TODO: store pid for each signal TODO: document file descriptor usage per loop TODO: store loop pid_t and compare isndie signal handler,store 1 for same, 2 for differign pid, clean up in loop_fork +TODO: embed watchers need updating when fd changes +TODO: document portability requirements for atomic pointer access +TODO: document requirements for function pointers and calling conventions. + +4.20 Sat Jun 20 13:01:43 CEST 2015 + - prefer noexcept over throw () with C++ 11. + - update ecb.h due to incompatibilities with c11. + - fix a potential aliasing issue when reading and writing + watcher callbacks. + +4.19 Thu Sep 25 08:18:25 CEST 2014 + - ev.h wasn't valid C++ anymore, which tripped compilers other than + clang, msvc or gcc (analyzed by Raphael 'kena' Poss). Unfortunately, + C++ doesn't support typedefs for function pointers fully, so the affected + declarations have to spell out the types each time. + - when not using autoconf, tighten the check for clock_gettime and related + functionality. + +4.18 Fri Sep 5 17:55:26 CEST 2014 + - events on files were not always generated properly with the + epoll backend (testcase by Assaf Inbal). + - mark event pipe fd as cloexec after a fork (analyzed by Sami Farin). + - (ecb) support m68k, m88k and sh (patch by Miod Vallat). + - use a reasonable fallback for EV_NSIG instead of erroring out + when we can't detect the signal set size. + - in the absence of autoconf, do not use the clock syscall + on glibc >= 2.17 (avoids the syscall AND -lrt on systems + doing clock_gettime in userspace). + - ensure extern "C" function pointers are used for externally-visible + loop callbacks (not watcher callbacks yet). + - (ecb) work around memory barriers and volatile apparently both being + broken in visual studio 2008 and later (analysed and patch by Nicolas Noble). + +4.15 Fri Mar 1 12:04:50 CET 2013 - destroying a non-default loop would stop the global waitpid watcher (Denis Bilenko). - queueing pending watchers of higher priority from a watcher now invokes @@ -33,10 +66,12 @@ TODO: store loop pid_t and compare isndie signal handler,store 1 for same, 2 for - (ecb) add memory fence support for gcc-alpha (Christian Weisgerber). - work around some kernels losing file descriptors by leaking the kqueue descriptor in the child. + - work around linux inotify not reporting IN_ATTRIB changes for directories + in many cases. - include sys/syscall.h instead of plain syscall.h. - check for io watcher loops in ev_verify, check for the most common reported usage bug in ev_io_start. - - chose socket vs. WSASocket at compiletime using EV_USE_WSASOCKET. + - choose socket vs. WSASocket at compiletime using EV_USE_WSASOCKET. - always use WSASend/WSARecv directly on windows, hoping that this works in all cases (unlike read/write/send/recv...). - try to detect signals around a fork faster (test program by @@ -45,8 +80,15 @@ TODO: store loop pid_t and compare isndie signal handler,store 1 for same, 2 for - rename ev::embed::set to ev::embed::set_embed to avoid clashing the watcher base set (loop) method. - rewrite the async/signal pipe logic to always keep a valid fd, which - simplifies (and hopefuly correctifies :) the race checking + simplifies (and hopefully correctifies :) the race checking on fork, at the cost of one extra fd. + - add fat, msdos, jffs2, ramfs, ntfs and btrfs to the list of + inotify-supporting filesystems. + - move orig_CFLAGS assignment to after AC_INIT, as newer autoconf + versions ignore it before + (https://bugzilla.redhat.com/show_bug.cgi?id=908096). + - add some untested android support. + - enum expressions must be of type int (reported by Juan Pablo L). 4.11 Sat Feb 4 19:52:39 CET 2012 - INCOMPATIBLE CHANGE: ev_timer_again now clears the pending status, as @@ -240,7 +282,7 @@ TODO: store loop pid_t and compare isndie signal handler,store 1 for same, 2 for - implement ev_suspend and ev_resume. - new EV_CUSTOM revents flag for use by applications. - add documentation section about priorities. - - add a glossary to the dcoumentation. + - add a glossary to the documentation. - extend the ev_fork description slightly. - optimize a jump out of call_pending. diff --git a/third_party/libev/LICENSE b/third_party/libev/LICENSE index 777d67caa660f83f3dfff4f06a355321012c2590..2fdabd48afad852a0ba6b3cbd388d579e06e6fc1 100644 --- a/third_party/libev/LICENSE +++ b/third_party/libev/LICENSE @@ -1,5 +1,5 @@ All files in libev are -Copyright (c)2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann. +Copyright (c)2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/third_party/libev/configure.ac b/third_party/libev/configure.ac index 31d0a25fe4e847203600ba9054254f4f5dec76e0..7ff79bf0aebf800b4f65f3cf0655871ff2520e86 100644 --- a/third_party/libev/configure.ac +++ b/third_party/libev/configure.ac @@ -1,9 +1,11 @@ +AC_INIT + orig_CFLAGS="$CFLAGS" -AC_INIT AC_CONFIG_SRCDIR([ev_epoll.c]) -AM_INIT_AUTOMAKE(libev,4.11) dnl also update ev.h! +dnl also update ev.h! +AM_INIT_AUTOMAKE(libev,4.20) AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE diff --git a/third_party/libev/ev++.h b/third_party/libev/ev++.h index ab7d0a651577ec749afbafcfeb1a44ac645ff554..4f0a36ab029d7f433792157644dcc07e59b7ae7e 100644 --- a/third_party/libev/ev++.h +++ b/third_party/libev/ev++.h @@ -575,7 +575,7 @@ namespace ev { } #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 */ #define EV_BEGIN_WATCHER(cppstem,cstem) \ \ diff --git a/third_party/libev/ev.3 b/third_party/libev/ev.3 index cc3d27de94c43fe6ac0403b9bc028d2e8a7950c1..003b7c1004b9a66feb7bbd994bf81cf530376a97 100644 --- a/third_party/libev/ev.3 +++ b/third_party/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.28) .\" .\" 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 "2012-05-26" "libev-4.11" "libev - high performance full featured event loop" +.TH LIBEV 3 "2015-05-01" "libev-4.19" "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 @@ -516,8 +525,10 @@ If this flag bit is or'ed into the flag value (or the program runs setuid or setgid) then libev will \fInot\fR look at the environment variable \&\f(CW\*(C`LIBEV_FLAGS\*(C'\fR. Otherwise (the default), this environment variable will override the flags completely if it is found in the environment. This is -useful to try out specific backends to test their performance, or to work -around bugs. +useful to try out specific backends to test their performance, to work +around bugs, or to make libev threadsafe (accessing environment variables +cannot be done in a threadsafe way, but usually it works if no other +thread modifies them). .ie n .IP """EVFLAG_FORKCHECK""" 4 .el .IP "\f(CWEVFLAG_FORKCHECK\fR" 4 .IX Item "EVFLAG_FORKCHECK" @@ -574,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 @@ -593,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 @@ -605,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 @@ -668,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 @@ -689,7 +700,7 @@ course). While stopping, setting and starting an I/O watcher does never cause an extra system call as with \f(CW\*(C`EVBACKEND_EPOLL\*(C'\fR, it still adds up to two event changes per incident. Support for \f(CW\*(C`fork ()\*(C'\fR is very bad (you might have to leak fd's on fork, but it's more sane than epoll) and it -drops fds silently in similarly hard-to-detect cases +drops fds silently in similarly hard-to-detect cases. .Sp This backend usually performs well under most conditions. .Sp @@ -698,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 @@ -712,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 @@ -801,13 +812,14 @@ If you need dynamically allocated loops it is better to use \f(CW\*(C`ev_loop_ne and \f(CW\*(C`ev_loop_destroy\*(C'\fR. .IP "ev_loop_fork (loop)" 4 .IX Item "ev_loop_fork (loop)" -This function sets a flag that causes subsequent \f(CW\*(C`ev_run\*(C'\fR iterations to -reinitialise the kernel state for backends that have one. Despite the -name, you can call it anytime, but it makes most sense after forking, in -the child process. You \fImust\fR call it (or use \f(CW\*(C`EVFLAG_FORKCHECK\*(C'\fR) in the -child before resuming or calling \f(CW\*(C`ev_run\*(C'\fR. -.Sp -Again, you \fIhave\fR to call it on \fIany\fR loop that you want to re-use after +This function sets a flag that causes subsequent \f(CW\*(C`ev_run\*(C'\fR iterations +to reinitialise the kernel state for backends that have one. Despite +the name, you can call it anytime you are allowed to start or stop +watchers (except inside an \f(CW\*(C`ev_prepare\*(C'\fR callback), but it makes most +sense after forking, in the child process. You \fImust\fR call it (or use +\&\f(CW\*(C`EVFLAG_FORKCHECK\*(C'\fR) in the child before resuming or calling \f(CW\*(C`ev_run\*(C'\fR. +.Sp +Again, you \fIhave\fR to call it on \fIany\fR loop that you want to re-use after a fork, \fIeven if you do not plan to use the loop in the parent\fR. This is because some kernel interfaces *cough* \fIkqueue\fR *cough* do funny things during fork. @@ -1354,7 +1366,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 @@ -1472,7 +1484,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)" @@ -1502,16 +1514,16 @@ 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 transition between them will be described in more detail \- and while these rules might look complicated, they usually do \*(L"the right thing\*(R". -.IP "initialiased" 4 -.IX Item "initialiased" +.IP "initialised" 4 +.IX Item "initialised" Before a watcher can be registered with the event loop it has to be initialised. This can be done with a call to \f(CW\*(C`ev_TYPE_init\*(C'\fR, or calls to \&\f(CW\*(C`ev_init\*(C'\fR followed by the watcher-specific \f(CW\*(C`ev_TYPE_set\*(C'\fR function. @@ -1557,7 +1569,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 @@ -1765,7 +1777,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 @@ -1773,7 +1785,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 @@ -1793,17 +1805,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 @@ -2152,15 +2164,17 @@ The relative timeouts are calculated relative to the \f(CW\*(C`ev_now ()\*(C'\fR time. This is usually the right thing as this timestamp refers to the time of the event triggering whatever timeout you are modifying/starting. If you suspect event processing to be delayed and you \fIneed\fR to base the -timeout on the current time, use something like this to adjust for this: +timeout on the current time, use something like the following to adjust +for it: .PP .Vb 1 -\& ev_timer_set (&timer, after + ev_now () \- ev_time (), 0.); +\& ev_timer_set (&timer, after + (ev_time () \- ev_now ()), 0.); .Ve .PP If the event loop is suspended for a long time, you can also force an update of the time returned by \f(CW\*(C`ev_now ()\*(C'\fR by calling \f(CW\*(C`ev_now_update -()\*(C'\fR. +()\*(C'\fR, although that will push the event time of all outstanding events +further into the future. .PP \fIThe special problem of unsynchronised clocks\fR .IX Subsection "The special problem of unsynchronised clocks" @@ -2418,7 +2432,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 @@ -2442,7 +2456,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 @@ -2544,9 +2558,9 @@ default loop and for \f(CW\*(C`SIGIO\*(C'\fR in another loop, but you cannot wat \&\f(CW\*(C`SIGINT\*(C'\fR in both the default loop and another loop at the same time. At the moment, \f(CW\*(C`SIGCHLD\*(C'\fR is permanently tied to the default loop. .PP -When the first watcher gets started will libev actually register something -with the kernel (thus it coexists with your own signal handlers as long as -you don't register any with libev for the same signal). +Only after the first watcher for a signal is started will libev actually +register something with the kernel. It thus coexists with your own signal +handlers as long as you don't register any with libev for the same signal. .PP If possible and supported, libev will install its handlers with \&\f(CW\*(C`SA_RESTART\*(C'\fR (or equivalent) behaviour enabled, so system calls should @@ -2577,7 +2591,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 @@ -2617,7 +2631,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 @@ -2742,8 +2756,9 @@ its completion. .IX Subsection "ev_stat - did the file attributes just change?" This watches a file system path for attribute changes. That is, it calls \&\f(CW\*(C`stat\*(C'\fR on that path in regular intervals (or when the \s-1OS\s0 says it changed) -and sees if it changed compared to the last time, invoking the callback if -it did. +and sees if it changed compared to the last time, invoking the callback +if it did. Starting the watcher \f(CW\*(C`stat\*(C'\fR's the file, so only changes that +happen after the watcher has been started will be reported. .PP The path does not need to exist: changing from \*(L"path exists\*(R" to \*(L"path does not exist\*(R" is a status change like any other. The condition \*(L"path does not @@ -2783,7 +2798,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 @@ -3038,13 +3053,13 @@ Prepare and check watchers are often (but not always) used in pairs: prepare watchers get invoked before the process blocks and check watchers afterwards. .PP -You \fImust not\fR call \f(CW\*(C`ev_run\*(C'\fR or similar functions that enter -the current event loop from either \f(CW\*(C`ev_prepare\*(C'\fR or \f(CW\*(C`ev_check\*(C'\fR -watchers. Other loops than the current one are fine, however. The -rationale behind this is that you do not need to check for recursion in -those watchers, i.e. the sequence will always be \f(CW\*(C`ev_prepare\*(C'\fR, blocking, -\&\f(CW\*(C`ev_check\*(C'\fR so if you have one watcher of each kind they will always be -called in pairs bracketing the blocking call. +You \fImust not\fR call \f(CW\*(C`ev_run\*(C'\fR (or similar functions that enter the +current event loop) or \f(CW\*(C`ev_loop_fork\*(C'\fR from either \f(CW\*(C`ev_prepare\*(C'\fR or +\&\f(CW\*(C`ev_check\*(C'\fR watchers. Other loops than the current one are fine, +however. The rationale behind this is that you do not need to check +for recursion in those watchers, i.e. the sequence will always be +\&\f(CW\*(C`ev_prepare\*(C'\fR, blocking, \f(CW\*(C`ev_check\*(C'\fR so if you have one watcher of each +kind they will always be called in pairs bracketing the blocking call. .PP Their main purpose is to integrate other event mechanisms into libev and their use is somewhat advanced. They could be used, for example, to track @@ -3224,7 +3239,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 @@ -3318,8 +3333,8 @@ as applicable. .IP "ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)" 4 .IX Item "ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)" .PD 0 -.IP "ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)" 4 -.IX Item "ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)" +.IP "ev_embed_set (ev_embed *, struct ev_loop *embedded_loop)" 4 +.IX Item "ev_embed_set (ev_embed *, struct ev_loop *embedded_loop)" .PD Configures the watcher to embed the given loop, which must be embeddable. If the callback is \f(CW0\fR, then \f(CW\*(C`ev_embed_sweep\*(C'\fR will be @@ -3348,7 +3363,7 @@ used). \& struct ev_loop *loop_hi = ev_default_init (0); \& struct ev_loop *loop_lo = 0; \& ev_embed embed; -\& +\& \& // see if there is a chance of getting one that works \& // (remember that a flags value of 0 means autodetection) \& loop_lo = ev_embeddable_backends () & ev_recommended_backends () @@ -3374,7 +3389,7 @@ kqueue implementation). Store the kqueue/socket\-only event loop in \& struct ev_loop *loop = ev_default_init (0); \& struct ev_loop *loop_socket = 0; \& ev_embed embed; -\& +\& \& if (ev_supported_backends () & ~ev_recommended_backends () & EVBACKEND_KQUEUE) \& if ((loop_socket = ev_loop_new (EVBACKEND_KQUEUE)) \& { @@ -3392,16 +3407,16 @@ kqueue implementation). Store the kqueue/socket\-only event loop in .IX Subsection "ev_fork - the audacity to resume the event loop after a fork" Fork watchers are called when a \f(CW\*(C`fork ()\*(C'\fR was detected (usually because whoever is a good citizen cared to tell libev about it by calling -\&\f(CW\*(C`ev_default_fork\*(C'\fR or \f(CW\*(C`ev_loop_fork\*(C'\fR). The invocation is done before the -event loop blocks next and before \f(CW\*(C`ev_check\*(C'\fR watchers are being called, -and only in the child after the fork. If whoever good citizen calling -\&\f(CW\*(C`ev_default_fork\*(C'\fR cheats and calls it in the wrong process, the fork -handlers will be invoked, too, of course. +\&\f(CW\*(C`ev_loop_fork\*(C'\fR). The invocation is done before the event loop blocks next +and before \f(CW\*(C`ev_check\*(C'\fR watchers are being called, and only in the child +after the fork. If whoever good citizen calling \f(CW\*(C`ev_default_fork\*(C'\fR cheats +and calls it in the wrong process, the fork handlers will be invoked, too, +of course. .PP \fIThe special problem of life after fork \- how is it possible?\fR .IX Subsection "The special problem of life after fork - how is it possible?" .PP -Most uses of \f(CW\*(C`fork()\*(C'\fR consist of forking, then some simple calls to set +Most uses of \f(CW\*(C`fork ()\*(C'\fR consist of forking, then some simple calls to set up/change the process environment, followed by a call to \f(CW\*(C`exec()\*(C'\fR. This sequence should be handled by libev without any problems. .PP @@ -3651,7 +3666,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) @@ -3677,7 +3692,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 @@ -3713,7 +3728,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 @@ -3751,7 +3766,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 @@ -3783,9 +3798,9 @@ already been invoked. A common way around all these issues is to make sure that \&\f(CW\*(C`start_new_request\*(C'\fR \fIalways\fR returns before the callback is invoked. If \&\f(CW\*(C`start_new_request\*(C'\fR immediately knows the result, it can artificially -delay invoking the callback by e.g. using a \f(CW\*(C`prepare\*(C'\fR or \f(CW\*(C`idle\*(C'\fR watcher -for example, or more sneakily, by reusing an existing (stopped) watcher -and pushing it into the pending queue: +delay invoking the callback by using a \f(CW\*(C`prepare\*(C'\fR or \f(CW\*(C`idle\*(C'\fR watcher for +example, or more sneakily, by reusing an existing (stopped) watcher and +pushing it into the pending queue: .PP .Vb 2 \& ev_set_cb (watcher, callback); @@ -3794,7 +3809,7 @@ and 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 @@ -3804,7 +3819,7 @@ This brings the problem of exiting \- a callback might want to finish the main \f(CW\*(C`ev_run\*(C'\fR call, but not the nested one (e.g. user clicked \*(L"Quit\*(R", but a modal \*(L"Are you sure?\*(R" dialog is still waiting), or just the nested one and not the main one (e.g. user clocked \*(L"Ok\*(R" in a modal dialog), or some -other combination: In these cases, \f(CW\*(C`ev_break\*(C'\fR will not work alone. +other combination: In these cases, a simple \f(CW\*(C`ev_break\*(C'\fR will not work. .PP The solution is to maintain \*(L"break this loop\*(R" variable for each \f(CW\*(C`ev_run\*(C'\fR invocation, and use a loop around \f(CW\*(C`ev_run\*(C'\fR until the condition is @@ -3836,7 +3851,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 @@ -3987,7 +4002,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 @@ -4033,13 +4048,13 @@ 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 \& // my_ev.h \& #define EV_CB_DECLARE(type) struct my_coro *cb; -\& #define EV_CB_INVOKE(watcher) switch_to ((watcher)\->cb); +\& #define EV_CB_INVOKE(watcher) switch_to ((watcher)\->cb) \& #include "../libev/ev.h" \& \& // my_ev.c @@ -4235,7 +4250,7 @@ Example: use a functor object as callback. \& ... \& } \& } -\& +\& \& myfunctor f; \& \& ev::io w; @@ -4263,10 +4278,14 @@ Associates a different \f(CW\*(C`struct ev_loop\*(C'\fR with this watcher. You c do this when the watcher is inactive (and not pending either). .IP "w\->set ([arguments])" 4 .IX Item "w->set ([arguments])" -Basically the same as \f(CW\*(C`ev_TYPE_set\*(C'\fR, with the same arguments. Either this -method or a suitable start method must be called at least once. Unlike the -C counterpart, an active watcher gets automatically stopped and restarted -when reconfiguring it with this method. +Basically the same as \f(CW\*(C`ev_TYPE_set\*(C'\fR (except for \f(CW\*(C`ev::embed\*(C'\fR watchers>), +with the same arguments. Either this method or a suitable start method +must be called at least once. Unlike the C counterpart, an active watcher +gets automatically stopped and restarted when reconfiguring it with this +method. +.Sp +For \f(CW\*(C`ev::embed\*(C'\fR watchers this method is called \f(CW\*(C`set_embed\*(C'\fR, to avoid +clashing with the \f(CW\*(C`set (loop)\*(C'\fR method. .IP "w\->start ()" 4 .IX Item "w->start ()" Starts the watcher. Note that there is no \f(CW\*(C`loop\*(C'\fR argument, as the @@ -4334,7 +4353,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" @@ -4352,7 +4371,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 @@ -4360,12 +4379,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. @@ -4464,7 +4483,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 @@ -4477,7 +4496,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 @@ -4511,10 +4530,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" @@ -4526,7 +4545,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 @@ -4535,7 +4554,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 @@ -4548,19 +4567,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 @@ -4575,7 +4594,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 @@ -4728,37 +4747,36 @@ different cpus (or different cpu cores). This reduces dependencies and makes libev faster. .IP "\s-1EV_NO_THREADS\s0" 4 .IX Item "EV_NO_THREADS" -If defined to be \f(CW1\fR, libev will assume that it will never be called -from different threads, which is a stronger assumption than \f(CW\*(C`EV_NO_SMP\*(C'\fR, -above. This reduces dependencies and makes libev faster. +If defined to be \f(CW1\fR, libev will assume that it will never be called from +different threads (that includes signal handlers), which is a stronger +assumption than \f(CW\*(C`EV_NO_SMP\*(C'\fR, above. This reduces dependencies and makes +libev faster. .IP "\s-1EV_ATOMIC_T\s0" 4 .IX Item "EV_ATOMIC_T" Libev requires an integer type (suitable for storing \f(CW0\fR or \f(CW1\fR) whose -access is atomic and serialised with respect to other threads or signal -contexts. No such type is easily found in the C language, so you can -provide your own type that you know is safe for your purposes. It is used -both for signal handler \*(L"locking\*(R" as well as for signal and thread safety -in \f(CW\*(C`ev_async\*(C'\fR watchers. +access is atomic with respect to other threads or signal contexts. No +such type is easily found in the C language, so you can provide your own +type that you know is safe for your purposes. It is used both for signal +handler \*(L"locking\*(R" as well as for signal and thread safety in \f(CW\*(C`ev_async\*(C'\fR +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, -although strictly speaking using a type that also implies a memory fence -is required. -.IP "\s-1EV_H\s0 (h)" 4 +(from \fIsignal.h\fR), which is usually good enough on most platforms. +.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 @@ -4792,8 +4810,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 @@ -4977,10 +4995,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)" @@ -4991,9 +5009,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 @@ -5055,7 +5073,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" @@ -5111,7 +5129,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" @@ -5126,7 +5144,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 @@ -5188,7 +5206,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. @@ -5197,13 +5215,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 @@ -5235,14 +5253,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" @@ -5269,13 +5287,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" @@ -5354,7 +5372,7 @@ libraries and raw winsocket select is: .Ve .PP Note that winsockets handling of fd sets is O(n), so you can easily get a -complexity in the O(nA\*^X) range when using win32. +complexity in the O(nX) range when using win32. .PP \fILimited number of file descriptors\fR .IX Subsection "Limited number of file descriptors" @@ -5380,8 +5398,8 @@ by calling \f(CW\*(C`_setmaxstdio\*(C'\fR, which can increase this limit to \f(C runtime libraries. This might get you to about \f(CW512\fR or \f(CW2048\fR sockets (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(nA\*^X)) will likely make this unworkable. -.SS "\s-1PORTABILITY\s0 \s-1REQUIREMENTS\s0" +the cost of calling select (O(nX)) will likely make this unworkable. +.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: @@ -5389,7 +5407,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. @@ -5415,12 +5433,12 @@ be compatible with libev. Interaction between \f(CW\*(C`sigprocmask\*(C'\fR and \&\f(CW\*(C`pthread_sigmask\*(C'\fR could complicate things, however. .Sp The most portable way to handle signals is to block signals in all threads -except the initial one, and run the default loop in the initial thread as -well. +except the initial one, and run the signal handling loop in the initial +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 @@ -5432,9 +5450,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). @@ -5506,7 +5524,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 @@ -5516,7 +5534,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 @@ -5566,7 +5584,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. @@ -5603,7 +5621,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 :) diff --git a/third_party/libev/ev.c b/third_party/libev/ev.c index 4a7998f81bb79e575a8aaeeae0c86234ea0a17f0..453000951624680321070d1f54b682b41c28ad89 100644 --- a/third_party/libev/ev.c +++ b/third_party/libev/ev.c @@ -1,7 +1,7 @@ /* * libev event processing core, watcher management * - * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de> + * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- @@ -45,11 +45,11 @@ # include "config.h" # endif -#if HAVE_FLOOR -# ifndef EV_USE_FLOOR -# define EV_USE_FLOOR 1 +# if HAVE_FLOOR +# ifndef EV_USE_FLOOR +# define EV_USE_FLOOR 1 +# endif # endif -#endif # if HAVE_CLOCK_SYSCALL # ifndef EV_USE_CLOCK_SYSCALL @@ -243,10 +243,7 @@ #elif defined _sys_nsig # define EV_NSIG (_sys_nsig) /* Solaris 2.5 */ #else -# error "unable to find value for NSIG, please report" -/* to make it compile regardless, just remove the above line, */ -/* but consider reporting it, too! :) */ -# define EV_NSIG 65 +# define EV_NSIG (8 * sizeof (sigset_t) + 1) #endif #ifndef EV_USE_FLOOR @@ -254,13 +251,22 @@ #endif #ifndef EV_USE_CLOCK_SYSCALL -# if __linux && __GLIBC__ >= 2 +# if __linux && __GLIBC__ == 2 && __GLIBC_MINOR__ < 17 # define EV_USE_CLOCK_SYSCALL EV_FEATURE_OS # else # define EV_USE_CLOCK_SYSCALL 0 # endif #endif +#if !(_POSIX_TIMERS > 0) +# ifndef EV_USE_MONOTONIC +# define EV_USE_MONOTONIC 0 +# endif +# ifndef EV_USE_REALTIME +# define EV_USE_REALTIME 0 +# endif +#endif + #ifndef EV_USE_MONOTONIC # if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0 # define EV_USE_MONOTONIC EV_FEATURE_OS @@ -359,6 +365,22 @@ # define EV_HEAP_CACHE_AT EV_FEATURE_DATA #endif +#ifdef ANDROID +/* supposedly, android doesn't typedef fd_mask */ +# undef EV_USE_SELECT +# define EV_USE_SELECT 0 +/* supposedly, we need to include syscall.h, not sys/syscall.h, so just disable */ +# undef EV_USE_CLOCK_SYSCALL +# define EV_USE_CLOCK_SYSCALL 0 +#endif + +/* aix's poll.h seems to cause lots of trouble */ +#ifdef _AIX +/* AIX has a completely broken poll.h header */ +# undef EV_USE_POLL +# define EV_USE_POLL 0 +#endif + /* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */ /* which makes programs even slower. might work on other unices, too. */ #if EV_USE_CLOCK_SYSCALL @@ -375,12 +397,6 @@ /* this block fixes any misconfiguration where we know we run into trouble otherwise */ -#ifdef _AIX -/* AIX has a completely broken poll.h header */ -# undef EV_USE_POLL -# define EV_USE_POLL 0 -#endif - #ifndef CLOCK_MONOTONIC # undef EV_USE_MONOTONIC # define EV_USE_MONOTONIC 0 @@ -477,7 +493,7 @@ struct signalfd_siginfo /* * libecb - http://software.schmorp.de/pkg/libecb * - * Copyright (©) 2009-2012 Marc Alexander Lehmann <libecb@schmorp.de> + * Copyright (©) 2009-2015 Marc Alexander Lehmann <libecb@schmorp.de> * Copyright (©) 2011 Emanuele Giaquinta * All rights reserved. * @@ -501,13 +517,24 @@ struct signalfd_siginfo * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. */ #ifndef ECB_H #define ECB_H /* 16 bits major, 16 bits minor */ -#define ECB_VERSION 0x00010001 +#define ECB_VERSION 0x00010004 #ifdef _WIN32 typedef signed char int8_t; @@ -532,7 +559,6 @@ struct signalfd_siginfo typedef uint32_t uintptr_t; typedef int32_t intptr_t; #endif - typedef intptr_t ptrdiff_t; #else #include <inttypes.h> #if UINTMAX_MAX > 0xffffffffU @@ -542,6 +568,18 @@ struct signalfd_siginfo #endif #endif +#define ECB_GCC_AMD64 (__amd64 || __amd64__ || __x86_64 || __x86_64__) +#define ECB_MSVC_AMD64 (_M_AMD64 || _M_X64) + +/* work around x32 idiocy by defining proper macros */ +#if ECB_GCC_AMD64 || ECB_MSVC_AMD64 + #if _ILP32 + #define ECB_AMD64_X32 1 + #else + #define ECB_AMD64 1 + #endif +#endif + /* many compilers define _GNUC_ to some versions but then only implement * what their idiot authors think are the "more important" extensions, * causing enormous grief in return for some better fake benchmark numbers. @@ -549,20 +587,50 @@ struct signalfd_siginfo * we try to detect these and simply assume they are not gcc - if they have * an issue with that they should have done it right in the first place. */ -#ifndef ECB_GCC_VERSION - #if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__ - #define ECB_GCC_VERSION(major,minor) 0 - #else - #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) - #endif +#if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__ + #define ECB_GCC_VERSION(major,minor) 0 +#else + #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) +#endif + +#define ECB_CLANG_VERSION(major,minor) (__clang_major__ > (major) || (__clang_major__ == (major) && __clang_minor__ >= (minor))) + +#if __clang__ && defined __has_builtin + #define ECB_CLANG_BUILTIN(x) __has_builtin (x) +#else + #define ECB_CLANG_BUILTIN(x) 0 +#endif + +#if __clang__ && defined __has_extension + #define ECB_CLANG_EXTENSION(x) __has_extension (x) +#else + #define ECB_CLANG_EXTENSION(x) 0 #endif -#define ECB_C (__STDC__+0) /* this assumes that __STDC__ is either empty or a number */ -#define ECB_C99 (__STDC_VERSION__ >= 199901L) -#define ECB_C11 (__STDC_VERSION__ >= 201112L) #define ECB_CPP (__cplusplus+0) #define ECB_CPP11 (__cplusplus >= 201103L) +#if ECB_CPP + #define ECB_C 0 + #define ECB_STDC_VERSION 0 +#else + #define ECB_C 1 + #define ECB_STDC_VERSION __STDC_VERSION__ +#endif + +#define ECB_C99 (ECB_STDC_VERSION >= 199901L) +#define ECB_C11 (ECB_STDC_VERSION >= 201112L) + +#if ECB_CPP + #define ECB_EXTERN_C extern "C" + #define ECB_EXTERN_C_BEG ECB_EXTERN_C { + #define ECB_EXTERN_C_END } +#else + #define ECB_EXTERN_C extern + #define ECB_EXTERN_C_BEG + #define ECB_EXTERN_C_END +#endif + /*****************************************************************************/ /* ECB_NO_THREADS - ecb is not used by multiple threads, ever */ @@ -576,13 +644,18 @@ struct signalfd_siginfo #define ECB_MEMORY_FENCE do { } while (0) #endif +/* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/compiler_ref/compiler_builtins.html */ +#if __xlC__ && ECB_CPP + #include <builtins.h> +#endif + #ifndef ECB_MEMORY_FENCE #if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110 #if __i386 || __i386__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory") #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory") #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("") - #elif __amd64 || __amd64__ || __x86_64 || __x86_64__ + #elif ECB_GCC_AMD64 #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory") #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory") #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("") @@ -594,14 +667,18 @@ struct signalfd_siginfo #elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \ || defined __ARM_ARCH_7M__ || defined __ARM_ARCH_7R__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory") - #elif __sparc || __sparc__ + #elif __aarch64__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb ish" : : : "memory") + #elif (__sparc || __sparc__) && !(__sparc_v8__ || defined __sparcv8) #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_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore") #elif defined __s390__ || defined __s390x__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("bcr 15,0" : : : "memory") #elif defined __mips__ - #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory") + /* GNU/Linux emulates sync on mips1 architectures, so we force its use */ + /* anybody else who still uses mips1 is supposed to send in their version, with detection code. */ + #define ECB_MEMORY_FENCE __asm__ __volatile__ (".set mips2; sync; .set mips0" : : : "memory") #elif defined __alpha__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mb" : : : "memory") #elif defined __hppa__ @@ -609,6 +686,12 @@ struct signalfd_siginfo #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("") #elif defined __ia64__ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mf" : : : "memory") + #elif defined __m68k__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory") + #elif defined __m88k__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("tb1 0,%%r0,128" : : : "memory") + #elif defined __sh__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory") #endif #endif #endif @@ -617,11 +700,23 @@ struct signalfd_siginfo #if ECB_GCC_VERSION(4,7) /* see comment below (stdatomic.h) about the C11 memory model. */ #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST) - #elif defined __clang && __has_feature (cxx_atomic) + #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE) + #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE) + + #elif ECB_CLANG_EXTENSION(c_atomic) /* see comment below (stdatomic.h) about the C11 memory model. */ #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST) + #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE) + #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE) + #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__ #define ECB_MEMORY_FENCE __sync_synchronize () + #elif _MSC_VER >= 1500 /* VC++ 2008 */ + /* apparently, microsoft broke all the memory barrier stuff in Visual Studio 2008... */ + #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier) + #define ECB_MEMORY_FENCE _ReadWriteBarrier (); MemoryBarrier() + #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier (); MemoryBarrier() /* according to msdn, _ReadBarrier is not a load fence */ + #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier (); MemoryBarrier() #elif _MSC_VER >= 1400 /* VC++ 2005 */ #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier) #define ECB_MEMORY_FENCE _ReadWriteBarrier () @@ -651,6 +746,8 @@ struct signalfd_siginfo /* for most usages, or gcc and clang have a bug */ /* I *currently* lean towards the latter, and inefficiently implement */ /* all three of ecb's fences as a seq_cst fence */ + /* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */ + /* for all __atomic_thread_fence's except seq_cst */ #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst) #endif #endif @@ -683,7 +780,7 @@ struct signalfd_siginfo /*****************************************************************************/ -#if __cplusplus +#if ECB_CPP #define ecb_inline static inline #elif ECB_GCC_VERSION(2,5) #define ecb_inline static __inline__ @@ -707,34 +804,82 @@ typedef int ecb_bool; #define ECB_CONCAT(a, b) ECB_CONCAT_(a, b) #define ECB_STRINGIFY_(a) # a #define ECB_STRINGIFY(a) ECB_STRINGIFY_(a) +#define ECB_STRINGIFY_EXPR(expr) ((expr), ECB_STRINGIFY_ (expr)) #define ecb_function_ ecb_inline -#if ECB_GCC_VERSION(3,1) - #define ecb_attribute(attrlist) __attribute__(attrlist) - #define ecb_is_constant(expr) __builtin_constant_p (expr) - #define ecb_expect(expr,value) __builtin_expect ((expr),(value)) - #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality) +#if ECB_GCC_VERSION(3,1) || ECB_CLANG_VERSION(2,8) + #define ecb_attribute(attrlist) __attribute__ (attrlist) #else #define ecb_attribute(attrlist) +#endif + +#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_constant_p) + #define ecb_is_constant(expr) __builtin_constant_p (expr) +#else + /* possible C11 impl for integral types + typedef struct ecb_is_constant_struct ecb_is_constant_struct; + #define ecb_is_constant(expr) _Generic ((1 ? (struct ecb_is_constant_struct *)0 : (void *)((expr) - (expr)), ecb_is_constant_struct *: 0, default: 1)) */ + #define ecb_is_constant(expr) 0 +#endif + +#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_expect) + #define ecb_expect(expr,value) __builtin_expect ((expr),(value)) +#else #define ecb_expect(expr,value) (expr) +#endif + +#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_prefetch) + #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality) +#else #define ecb_prefetch(addr,rw,locality) #endif /* no emulation for ecb_decltype */ -#if ECB_GCC_VERSION(4,5) - #define ecb_decltype(x) __decltype(x) -#elif ECB_GCC_VERSION(3,0) - #define ecb_decltype(x) __typeof(x) +#if ECB_CPP11 + // older implementations might have problems with decltype(x)::type, work around it + template<class T> struct ecb_decltype_t { typedef T type; }; + #define ecb_decltype(x) ecb_decltype_t<decltype (x)>::type +#elif ECB_GCC_VERSION(3,0) || ECB_CLANG_VERSION(2,8) + #define ecb_decltype(x) __typeof__ (x) +#endif + +#if _MSC_VER >= 1300 + #define ecb_deprecated __declspec (deprecated) +#else + #define ecb_deprecated ecb_attribute ((__deprecated__)) +#endif + +#if _MSC_VER >= 1500 + #define ecb_deprecated_message(msg) __declspec (deprecated (msg)) +#elif ECB_GCC_VERSION(4,5) + #define ecb_deprecated_message(msg) ecb_attribute ((__deprecated__ (msg)) +#else + #define ecb_deprecated_message(msg) ecb_deprecated +#endif + +#if _MSC_VER >= 1400 + #define ecb_noinline __declspec (noinline) +#else + #define ecb_noinline ecb_attribute ((__noinline__)) #endif -#define ecb_noinline ecb_attribute ((__noinline__)) #define ecb_unused ecb_attribute ((__unused__)) #define ecb_const ecb_attribute ((__const__)) #define ecb_pure ecb_attribute ((__pure__)) -#define ecb_noreturn ecb_attribute ((__noreturn__)) +#if ECB_C11 || __IBMC_NORETURN + /* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/language_ref/noreturn.html */ + #define ecb_noreturn _Noreturn +#elif ECB_CPP11 + #define ecb_noreturn [[noreturn]] +#elif _MSC_VER >= 1200 + /* http://msdn.microsoft.com/en-us/library/k6ktzx3s.aspx */ + #define ecb_noreturn __declspec (noreturn) +#else + #define ecb_noreturn ecb_attribute ((__noreturn__)) +#endif #if ECB_GCC_VERSION(4,3) #define ecb_artificial ecb_attribute ((__artificial__)) @@ -756,7 +901,10 @@ typedef int ecb_bool; #define ecb_unlikely(expr) ecb_expect_false (expr) /* count trailing zero bits and count # of one bits */ -#if ECB_GCC_VERSION(3,4) +#if ECB_GCC_VERSION(3,4) \ + || (ECB_CLANG_BUILTIN(__builtin_clz) && ECB_CLANG_BUILTIN(__builtin_clzll) \ + && ECB_CLANG_BUILTIN(__builtin_ctz) && ECB_CLANG_BUILTIN(__builtin_ctzll) \ + && ECB_CLANG_BUILTIN(__builtin_popcount)) /* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */ #define ecb_ld32(x) (__builtin_clz (x) ^ 31) #define ecb_ld64(x) (__builtin_clzll (x) ^ 63) @@ -765,8 +913,8 @@ typedef int ecb_bool; #define ecb_popcount32(x) __builtin_popcount (x) /* no popcountll */ #else - ecb_function_ int ecb_ctz32 (uint32_t x) ecb_const; - ecb_function_ int + ecb_function_ ecb_const int ecb_ctz32 (uint32_t x); + ecb_function_ ecb_const int ecb_ctz32 (uint32_t x) { int r = 0; @@ -790,16 +938,16 @@ typedef int ecb_bool; return r; } - ecb_function_ int ecb_ctz64 (uint64_t x) ecb_const; - ecb_function_ int + ecb_function_ ecb_const int ecb_ctz64 (uint64_t x); + ecb_function_ ecb_const int ecb_ctz64 (uint64_t x) { int shift = x & 0xffffffffU ? 0 : 32; return ecb_ctz32 (x >> shift) + shift; } - ecb_function_ int ecb_popcount32 (uint32_t x) ecb_const; - ecb_function_ int + ecb_function_ ecb_const int ecb_popcount32 (uint32_t x); + ecb_function_ ecb_const int ecb_popcount32 (uint32_t x) { x -= (x >> 1) & 0x55555555; @@ -810,8 +958,8 @@ typedef int ecb_bool; return x >> 24; } - ecb_function_ int ecb_ld32 (uint32_t x) ecb_const; - ecb_function_ 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) { int r = 0; @@ -824,8 +972,8 @@ typedef int ecb_bool; return r; } - ecb_function_ int ecb_ld64 (uint64_t x) ecb_const; - ecb_function_ 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) { int r = 0; @@ -835,20 +983,20 @@ typedef int ecb_bool; } #endif -ecb_function_ ecb_bool ecb_is_pot32 (uint32_t x) ecb_const; -ecb_function_ ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); } -ecb_function_ ecb_bool ecb_is_pot64 (uint64_t x) ecb_const; -ecb_function_ ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); } +ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x); +ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); } +ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x); +ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); } -ecb_function_ uint8_t ecb_bitrev8 (uint8_t x) ecb_const; -ecb_function_ uint8_t ecb_bitrev8 (uint8_t x) +ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x); +ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x) { return ( (x * 0x0802U & 0x22110U) - | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16; + | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16; } -ecb_function_ uint16_t ecb_bitrev16 (uint16_t x) ecb_const; -ecb_function_ uint16_t ecb_bitrev16 (uint16_t x) +ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x); +ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x) { x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1); x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2); @@ -858,8 +1006,8 @@ ecb_function_ uint16_t ecb_bitrev16 (uint16_t x) return x; } -ecb_function_ uint32_t ecb_bitrev32 (uint32_t x) ecb_const; -ecb_function_ uint32_t ecb_bitrev32 (uint32_t x) +ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x); +ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x) { x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1); x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2); @@ -872,81 +1020,108 @@ ecb_function_ uint32_t ecb_bitrev32 (uint32_t x) /* popcount64 is only available on 64 bit cpus as gcc builtin */ /* so for this version we are lazy */ -ecb_function_ int ecb_popcount64 (uint64_t x) ecb_const; -ecb_function_ int +ecb_function_ ecb_const int ecb_popcount64 (uint64_t x); +ecb_function_ ecb_const int ecb_popcount64 (uint64_t x) { return ecb_popcount32 (x) + ecb_popcount32 (x >> 32); } -ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) ecb_const; -ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) ecb_const; -ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) ecb_const; -ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) ecb_const; -ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) ecb_const; -ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) ecb_const; -ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) ecb_const; -ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) ecb_const; - -ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); } -ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); } -ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); } -ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); } -ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); } -ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); } -ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); } -ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); } - -#if ECB_GCC_VERSION(4,3) +ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count); +ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count); +ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count); +ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count); +ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count); +ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count); +ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count); +ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count); + +ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); } +ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); } +ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); } +ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); } +ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); } +ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); } +ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); } +ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); } + +#if ECB_GCC_VERSION(4,3) || (ECB_CLANG_BUILTIN(__builtin_bswap32) && ECB_CLANG_BUILTIN(__builtin_bswap64)) + #if ECB_GCC_VERSION(4,8) || ECB_CLANG_BUILTIN(__builtin_bswap16) + #define ecb_bswap16(x) __builtin_bswap16 (x) + #else #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16) + #endif #define ecb_bswap32(x) __builtin_bswap32 (x) #define ecb_bswap64(x) __builtin_bswap64 (x) +#elif _MSC_VER + #include <stdlib.h> + #define ecb_bswap16(x) ((uint16_t)_byteswap_ushort ((uint16_t)(x))) + #define ecb_bswap32(x) ((uint32_t)_byteswap_ulong ((uint32_t)(x))) + #define ecb_bswap64(x) ((uint64_t)_byteswap_uint64 ((uint64_t)(x))) #else - ecb_function_ uint16_t ecb_bswap16 (uint16_t x) ecb_const; - ecb_function_ uint16_t + ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x); + ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x) { return ecb_rotl16 (x, 8); } - ecb_function_ uint32_t ecb_bswap32 (uint32_t x) ecb_const; - ecb_function_ uint32_t + ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x); + ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x) { return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16); } - ecb_function_ uint64_t ecb_bswap64 (uint64_t x) ecb_const; - ecb_function_ uint64_t + ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x); + ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x) { return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32); } #endif -#if ECB_GCC_VERSION(4,5) +#if ECB_GCC_VERSION(4,5) || ECB_CLANG_BUILTIN(__builtin_unreachable) #define ecb_unreachable() __builtin_unreachable () #else /* this seems to work fine, but gcc always emits a warning for it :/ */ - ecb_inline void ecb_unreachable (void) ecb_noreturn; - ecb_inline void ecb_unreachable (void) { } + ecb_inline ecb_noreturn void ecb_unreachable (void); + ecb_inline ecb_noreturn void ecb_unreachable (void) { } #endif /* try to tell the compiler that some condition is definitely true */ -#define ecb_assume(cond) do { if (!(cond)) ecb_unreachable (); } while (0) +#define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0 -ecb_inline unsigned char ecb_byteorder_helper (void) ecb_const; -ecb_inline unsigned char +ecb_inline ecb_const unsigned char ecb_byteorder_helper (void); +ecb_inline ecb_const unsigned char ecb_byteorder_helper (void) { - const uint32_t u = 0x11223344; - return *(unsigned char *)&u; + /* the union code still generates code under pressure in gcc, */ + /* but less than using pointers, and always seems to */ + /* successfully return a constant. */ + /* the reason why we have this horrible preprocessor mess */ + /* is to avoid it in all cases, at least on common architectures */ + /* 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; +#else + union + { + uint32_t i; + uint8_t c; + } u = { 0x11223344 }; + return u.c; +#endif } -ecb_inline ecb_bool ecb_big_endian (void) ecb_const; -ecb_inline ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; } -ecb_inline ecb_bool ecb_little_endian (void) ecb_const; -ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; } +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_little_endian (void); +ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; } #if ECB_GCC_VERSION(3,0) || ECB_C99 #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0)) @@ -954,7 +1129,7 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n))) #endif -#if __cplusplus +#if ECB_CPP template<typename T> static inline T ecb_div_rd (T val, T div) { @@ -981,6 +1156,216 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == #define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) #endif +/*******************************************************************************/ +/* floating point stuff, can be disabled by defining ECB_NO_LIBM */ + +/* basically, everything uses "ieee pure-endian" floating point numbers */ +/* the only noteworthy exception is ancient armle, which uses order 43218765 */ +#if 0 \ + || __i386 || __i386__ \ + || ECB_GCC_AMD64 \ + || __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \ + || defined __s390__ || defined __s390x__ \ + || defined __mips__ \ + || defined __alpha__ \ + || defined __hppa__ \ + || defined __ia64__ \ + || defined __m68k__ \ + || defined __m88k__ \ + || defined __sh__ \ + || defined _M_IX86 || defined ECB_MSVC_AMD64 || defined _M_IA64 \ + || (defined __arm__ && (defined __ARM_EABI__ || defined __EABI__ || defined __VFP_FP__ || defined _WIN32_WCE || defined __ANDROID__)) \ + || defined __aarch64__ + #define ECB_STDFP 1 + #include <string.h> /* for memcpy */ +#else + #define ECB_STDFP 0 +#endif + +#ifndef ECB_NO_LIBM + + #include <math.h> /* for frexp*, ldexp*, INFINITY, NAN */ + + /* only the oldest of old doesn't have this one. solaris. */ + #ifdef INFINITY + #define ECB_INFINITY INFINITY + #else + #define ECB_INFINITY HUGE_VAL + #endif + + #ifdef NAN + #define ECB_NAN NAN + #else + #define ECB_NAN ECB_INFINITY + #endif + + #if ECB_C99 || _XOPEN_VERSION >= 600 || _POSIX_VERSION >= 200112L + #define ecb_ldexpf(x,e) ldexpf ((x), (e)) + #define ecb_frexpf(x,e) frexpf ((x), (e)) + #else + #define ecb_ldexpf(x,e) (float) ldexp ((double) (x), (e)) + #define ecb_frexpf(x,e) (float) frexp ((double) (x), (e)) + #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 */ + ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x); + ecb_function_ ecb_const uint32_t + ecb_float_to_binary32 (float x) + { + uint32_t r; + + #if ECB_STDFP + memcpy (&r, &x, 4); + #else + /* slow emulation, works for anything but -0 */ + uint32_t m; + int e; + + if (x == 0e0f ) return 0x00000000U; + if (x > +3.40282346638528860e+38f) return 0x7f800000U; + if (x < -3.40282346638528860e+38f) return 0xff800000U; + if (x != x ) return 0x7fbfffffU; + + m = ecb_frexpf (x, &e) * 0x1000000U; + + r = m & 0x80000000U; + + if (r) + m = -m; + + if (e <= -126) + { + m &= 0xffffffU; + m >>= (-125 - e); + e = -126; + } + + r |= (e + 126) << 23; + r |= m & 0x7fffffU; + #endif + + return r; + } + + /* converts an ieee single/binary32 to a float */ + ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x); + ecb_function_ ecb_const float + ecb_binary32_to_float (uint32_t x) + { + float r; + + #if ECB_STDFP + memcpy (&r, &x, 4); + #else + /* emulation, only works for normals and subnormals and +0 */ + int neg = x >> 31; + int e = (x >> 23) & 0xffU; + + x &= 0x7fffffU; + + if (e) + x |= 0x800000U; + else + e = 1; + + /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */ + r = ecb_ldexpf (x * (0.5f / 0x800000U), e - 126); + + r = neg ? -r : r; + #endif + + return r; + } + + /* convert a double to ieee double/binary64 */ + ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x); + ecb_function_ ecb_const uint64_t + ecb_double_to_binary64 (double x) + { + uint64_t r; + + #if ECB_STDFP + memcpy (&r, &x, 8); + #else + /* slow emulation, works for anything but -0 */ + uint64_t m; + int e; + + if (x == 0e0 ) return 0x0000000000000000U; + if (x > +1.79769313486231470e+308) return 0x7ff0000000000000U; + if (x < -1.79769313486231470e+308) return 0xfff0000000000000U; + if (x != x ) return 0X7ff7ffffffffffffU; + + m = frexp (x, &e) * 0x20000000000000U; + + r = m & 0x8000000000000000;; + + if (r) + m = -m; + + if (e <= -1022) + { + m &= 0x1fffffffffffffU; + m >>= (-1021 - e); + e = -1022; + } + + r |= ((uint64_t)(e + 1022)) << 52; + r |= m & 0xfffffffffffffU; + #endif + + return r; + } + + /* converts an ieee double/binary64 to a double */ + ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x); + ecb_function_ ecb_const double + ecb_binary64_to_double (uint64_t x) + { + double r; + + #if ECB_STDFP + memcpy (&r, &x, 8); + #else + /* emulation, only works for normals and subnormals and +0 */ + int neg = x >> 63; + int e = (x >> 52) & 0x7ffU; + + x &= 0xfffffffffffffU; + + if (e) + x |= 0x10000000000000U; + else + e = 1; + + /* we distrust ldexp a bit and do the 2**-53 scaling by an extra multiply */ + r = ldexp (x * (0.5 / 0x10000000000000U), e - 1022); + + r = neg ? -r : r; + #endif + + return r; + } + +#endif + #endif /* ECB.H END */ @@ -1887,8 +2272,6 @@ evpipe_init (EV_P) fd_intern (fds [0]); } - fd_intern (fds [1]); - evpipe [0] = fds [0]; if (evpipe [1] < 0) @@ -1904,6 +2287,8 @@ evpipe_init (EV_P) close (fds [1]); } + fd_intern (evpipe [1]); + ev_io_set (&pipe_w, evpipe [0] < 0 ? evpipe [1] : evpipe [0], EV_READ); ev_io_start (EV_A_ &pipe_w); ev_unref (EV_A); /* watcher should not keep loop alive */ @@ -2031,7 +2416,9 @@ void ev_feed_signal (int signum) EV_THROW { #if EV_MULTIPLICITY - EV_P = signals [signum - 1].loop; + EV_P; + ECB_MEMORY_FENCE_ACQUIRE; + EV_A = signals [signum - 1].loop; if (!EV_A) return; @@ -2294,7 +2681,7 @@ ev_userdata (EV_P) EV_THROW } void -ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P)) EV_THROW +ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW { invoke_cb = invoke_pending_cb; } @@ -3535,6 +3922,7 @@ ev_signal_start (EV_P_ ev_signal *w) EV_THROW !signals [w->signum - 1].loop || signals [w->signum - 1].loop == loop)); signals [w->signum - 1].loop = EV_A; + ECB_MEMORY_FENCE_RELEASE; #endif EV_FREQUENT_CHECK; @@ -3699,7 +4087,10 @@ static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents); static void noinline infy_add (EV_P_ ev_stat *w) { - w->wd = inotify_add_watch (fs_fd, w->path, IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY | IN_DONT_FOLLOW | IN_MASK_ADD); + w->wd = inotify_add_watch (fs_fd, w->path, + IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY + | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO + | IN_DONT_FOLLOW | IN_MASK_ADD); if (w->wd >= 0) { @@ -3713,10 +4104,16 @@ infy_add (EV_P_ ev_stat *w) w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL; else if (!statfs (w->path, &sfs) && (sfs.f_type == 0x1373 /* devfs */ + || sfs.f_type == 0x4006 /* fat */ + || sfs.f_type == 0x4d44 /* msdos */ || sfs.f_type == 0xEF53 /* ext2/3 */ + || sfs.f_type == 0x72b6 /* jffs2 */ + || sfs.f_type == 0x858458f6 /* ramfs */ + || sfs.f_type == 0x5346544e /* ntfs */ || sfs.f_type == 0x3153464a /* jfs */ + || sfs.f_type == 0x9123683e /* btrfs */ || sfs.f_type == 0x52654973 /* reiser3 */ - || sfs.f_type == 0x01021994 /* tempfs */ + || sfs.f_type == 0x01021994 /* tmpfs */ || sfs.f_type == 0x58465342 /* xfs */)) w->timer.repeat = 0.; /* filesystem is local, kernel new enough */ else diff --git a/third_party/libev/ev.h b/third_party/libev/ev.h index 9c57f7393dc6d697fba88a59868e556af067e87a..5ecf16a5e26b4a0005ecf266f4bcb6cefa1c8afb 100644 --- a/third_party/libev/ev.h +++ b/third_party/libev/ev.h @@ -1,7 +1,7 @@ /* * libev native API header * - * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de> + * Copyright (c) 2007,2008,2009,2010,2011,2012,2015 Marc Alexander Lehmann <libev@schmorp.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- @@ -42,12 +42,16 @@ #ifdef __cplusplus # define EV_CPP(x) x +# if __cplusplus >= 201103L +# define EV_THROW noexcept +# else +# define EV_THROW throw () +# endif #else # define EV_CPP(x) +# define EV_THROW #endif -#define EV_THROW EV_CPP(throw()) - EV_CPP(extern "C" {) /*****************************************************************************/ @@ -148,6 +152,8 @@ EV_CPP(extern "C" {) typedef double ev_tstamp; +#include <string.h> /* for memmove */ + #ifndef EV_ATOMIC_T # include <signal.h> # define EV_ATOMIC_T sig_atomic_t volatile @@ -205,33 +211,33 @@ struct ev_loop; /*****************************************************************************/ #define EV_VERSION_MAJOR 4 -#define EV_VERSION_MINOR 11 +#define EV_VERSION_MINOR 20 /* eventmask, revents, events... */ enum { - EV_UNDEF = 0xFFFFFFFF, /* guaranteed to be invalid */ - EV_NONE = 0x00, /* no events */ - EV_READ = 0x01, /* ev_io detected read will not block */ - EV_WRITE = 0x02, /* ev_io detected write will not block */ - EV__IOFDSET = 0x80, /* internal use only */ - EV_IO = EV_READ, /* alias for type-detection */ - EV_TIMER = 0x00000100, /* timer timed out */ + EV_UNDEF = (int)0xFFFFFFFF, /* guaranteed to be invalid */ + EV_NONE = 0x00, /* no events */ + EV_READ = 0x01, /* ev_io detected read will not block */ + EV_WRITE = 0x02, /* ev_io detected write will not block */ + EV__IOFDSET = 0x80, /* internal use only */ + EV_IO = EV_READ, /* alias for type-detection */ + EV_TIMER = 0x00000100, /* timer timed out */ #if EV_COMPAT3 - EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */ -#endif - EV_PERIODIC = 0x00000200, /* periodic timer timed out */ - EV_SIGNAL = 0x00000400, /* signal was received */ - EV_CHILD = 0x00000800, /* child/pid had status change */ - EV_STAT = 0x00001000, /* stat data changed */ - EV_IDLE = 0x00002000, /* event loop is idling */ - EV_PREPARE = 0x00004000, /* event loop about to poll */ - EV_CHECK = 0x00008000, /* event loop finished poll */ - EV_EMBED = 0x00010000, /* embedded event loop needs sweep */ - EV_FORK = 0x00020000, /* event loop resumed in child */ - EV_CLEANUP = 0x00040000, /* event loop resumed in child */ - EV_ASYNC = 0x00080000, /* async intra-loop signal */ - EV_CUSTOM = 0x01000000, /* for use by user code */ - EV_ERROR = 0x80000000 /* sent when an error occurs */ + EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */ +#endif + EV_PERIODIC = 0x00000200, /* periodic timer timed out */ + EV_SIGNAL = 0x00000400, /* signal was received */ + EV_CHILD = 0x00000800, /* child/pid had status change */ + EV_STAT = 0x00001000, /* stat data changed */ + EV_IDLE = 0x00002000, /* event loop is idling */ + EV_PREPARE = 0x00004000, /* event loop about to poll */ + EV_CHECK = 0x00008000, /* event loop finished poll */ + EV_EMBED = 0x00010000, /* embedded event loop needs sweep */ + EV_FORK = 0x00020000, /* event loop resumed in child */ + EV_CLEANUP = 0x00040000, /* event loop resumed in child */ + EV_ASYNC = 0x00080000, /* async intra-loop signal */ + EV_CUSTOM = 0x01000000, /* for use by user code */ + EV_ERROR = (int)0x80000000 /* sent when an error occurs */ }; /* can be used to add custom fields to all watchers, while losing binary compatibility */ @@ -658,8 +664,10 @@ EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_T /* advanced stuff for threading etc. support, see docs */ EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_THROW; EV_API_DECL void *ev_userdata (EV_P) EV_THROW; -EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P)) EV_THROW; -EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P) EV_THROW) EV_THROW; +typedef void (*ev_loop_callback)(EV_P); +EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW; +/* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out */ +EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW; EV_API_DECL unsigned int ev_pending_count (EV_P) EV_THROW; /* number of pending events, if any */ EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */ @@ -713,7 +721,8 @@ EV_API_DECL void ev_resume (EV_P) EV_THROW; #define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */ #define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */ -#define ev_cb(ev) (ev)->cb /* rw */ +#define ev_cb_(ev) (ev)->cb /* rw */ +#define ev_cb(ev) (memmove (&ev_cb_ (ev), &((ev_watcher *)(ev))->cb, sizeof (ev_cb_ (ev))), (ev)->cb) #if EV_MINPRI == EV_MAXPRI # define ev_priority(ev) ((ev), EV_MINPRI) @@ -726,16 +735,16 @@ EV_API_DECL void ev_resume (EV_P) EV_THROW; #define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at) #ifndef ev_set_cb -# define ev_set_cb(ev,cb_) ev_cb (ev) = (cb_) +# define ev_set_cb(ev,cb_) (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev)))) #endif /* stopping (enabling, adding) a watcher does nothing if it is already running */ -/* stopping (disabling, deleting) a watcher does nothing unless its already running */ +/* stopping (disabling, deleting) a watcher does nothing unless it's already running */ #if EV_PROTOTYPES /* feeds an event into a watcher as if the event actually occurred */ /* accepts any ev_watcher type */ -EV_API_DECL int ev_activecnt (EV_P) EV_THROW; +EV_API_DECL int ev_activecnt (EV_P) EV_THROW; EV_API_DECL void ev_feed_event (EV_P_ void *w, int revents) EV_THROW; EV_API_DECL void ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW; #if EV_SIGNAL_ENABLE diff --git a/third_party/libev/ev.pod b/third_party/libev/ev.pod index 1e285892915e381152b6c96b5da1afee1195f689..b67bc859faa131686c13d8b54c3beaf0407e0e3b 100644 --- a/third_party/libev/ev.pod +++ b/third_party/libev/ev.pod @@ -1,3 +1,5 @@ +=encoding utf-8 + =head1 NAME libev - a high performance full-featured event loop written in C @@ -398,8 +400,10 @@ If this flag bit is or'ed into the flag value (or the program runs setuid or setgid) then libev will I<not> look at the environment variable C<LIBEV_FLAGS>. Otherwise (the default), this environment variable will override the flags completely if it is found in the environment. This is -useful to try out specific backends to test their performance, or to work -around bugs. +useful to try out specific backends to test their performance, to work +around bugs, or to make libev threadsafe (accessing environment variables +cannot be done in a threadsafe way, but usually it works if no other +thread modifies them). =item C<EVFLAG_FORKCHECK> @@ -571,7 +575,7 @@ course). While stopping, setting and starting an I/O watcher does never cause an extra system call as with C<EVBACKEND_EPOLL>, it still adds up to two event changes per incident. Support for C<fork ()> is very bad (you might have to leak fd's on fork, but it's more sane than epoll) and it -drops fds silently in similarly hard-to-detect cases +drops fds silently in similarly hard-to-detect cases. This backend usually performs well under most conditions. @@ -680,13 +684,14 @@ and C<ev_loop_destroy>. =item ev_loop_fork (loop) -This function sets a flag that causes subsequent C<ev_run> iterations to -reinitialise the kernel state for backends that have one. Despite the -name, you can call it anytime, but it makes most sense after forking, in -the child process. You I<must> call it (or use C<EVFLAG_FORKCHECK>) in the -child before resuming or calling C<ev_run>. +This function sets a flag that causes subsequent C<ev_run> iterations +to reinitialise the kernel state for backends that have one. Despite +the name, you can call it anytime you are allowed to start or stop +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 +C<EVFLAG_FORKCHECK>) in the child before resuming or calling C<ev_run>. -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 because some kernel interfaces *cough* I<kqueue> *cough* do funny things during fork. @@ -1395,7 +1400,7 @@ rules might look complicated, they usually do "the right thing". =over 4 -=item initialiased +=item initialised Before a watcher can be registered with the event loop it has to be initialised. This can be done with a call to C<ev_TYPE_init>, or calls to @@ -2026,13 +2031,15 @@ The relative timeouts are calculated relative to the C<ev_now ()> time. This is usually the right thing as this timestamp refers to the time of the event triggering whatever timeout you are modifying/starting. If you suspect event processing to be delayed and you I<need> to base the -timeout on the current time, use something like this to adjust for this: +timeout on the current time, use something like the following to adjust +for it: - ev_timer_set (&timer, after + ev_now () - ev_time (), 0.); + ev_timer_set (&timer, after + (ev_time () - ev_now ()), 0.); If the event loop is suspended for a long time, you can also force an update of the time returned by C<ev_now ()> by calling C<ev_now_update -()>. +()>, although that will push the event time of all outstanding events +further into the future. =head3 The special problem of unsynchronised clocks @@ -2391,7 +2398,7 @@ Example: Call a callback every hour, starting now: ev_periodic_init (&hourly_tick, clock_cb, fmod (ev_now (loop), 3600.), 3600., 0); ev_periodic_start (loop, &hourly_tick); - + =head2 C<ev_signal> - signal me when a signal gets signalled! @@ -2411,9 +2418,9 @@ default loop and for C<SIGIO> in another loop, but you cannot watch for C<SIGINT> in both the default loop and another loop at the same time. At the moment, C<SIGCHLD> is permanently tied to the default loop. -When the first watcher gets started will libev actually register something -with the kernel (thus it coexists with your own signal handlers as long as -you don't register any with libev for the same signal). +Only after the first watcher for a signal is started will libev actually +register something with the kernel. It thus coexists with your own signal +handlers as long as you don't register any with libev for the same signal. If possible and supported, libev will install its handlers with C<SA_RESTART> (or equivalent) behaviour enabled, so system calls should @@ -2608,8 +2615,9 @@ its completion. This watches a file system path for attribute changes. That is, it calls C<stat> on that path in regular intervals (or when the OS says it changed) -and sees if it changed compared to the last time, invoking the callback if -it did. +and sees if it changed compared to the last time, invoking the callback +if it did. Starting the watcher C<stat>'s the file, so only changes that +happen after the watcher has been started will be reported. The path does not need to exist: changing from "path exists" to "path does not exist" is a status change like any other. The condition "path does not @@ -2904,13 +2912,13 @@ Prepare and check watchers are often (but not always) used in pairs: prepare watchers get invoked before the process blocks and check watchers afterwards. -You I<must not> call C<ev_run> or similar functions that enter -the current event loop from either C<ev_prepare> or C<ev_check> -watchers. Other loops than the current one are fine, however. The -rationale behind this is that you do not need to check for recursion in -those watchers, i.e. the sequence will always be C<ev_prepare>, blocking, -C<ev_check> so if you have one watcher of each kind they will always be -called in pairs bracketing the blocking call. +You I<must not> call C<ev_run> (or similar functions that enter the +current event loop) or C<ev_loop_fork> from either C<ev_prepare> or +C<ev_check> watchers. Other loops than the current one are fine, +however. The rationale behind this is that you do not need to check +for recursion in those watchers, i.e. the sequence will always be +C<ev_prepare>, blocking, C<ev_check> so if you have one watcher of each +kind they will always be called in pairs bracketing the blocking call. Their main purpose is to integrate other event mechanisms into libev and their use is somewhat advanced. They could be used, for example, to track @@ -3179,7 +3187,7 @@ as applicable. =item ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop) -=item ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop) +=item ev_embed_set (ev_embed *, struct ev_loop *embedded_loop) Configures the watcher to embed the given loop, which must be embeddable. If the callback is C<0>, then C<ev_embed_sweep> will be @@ -3210,7 +3218,7 @@ used). struct ev_loop *loop_hi = ev_default_init (0); struct ev_loop *loop_lo = 0; ev_embed embed; - + // see if there is a chance of getting one that works // (remember that a flags value of 0 means autodetection) loop_lo = ev_embeddable_backends () & ev_recommended_backends () @@ -3234,7 +3242,7 @@ C<loop_socket>. (One might optionally use C<EVFLAG_NOENV>, too). struct ev_loop *loop = ev_default_init (0); struct ev_loop *loop_socket = 0; ev_embed embed; - + if (ev_supported_backends () & ~ev_recommended_backends () & EVBACKEND_KQUEUE) if ((loop_socket = ev_loop_new (EVBACKEND_KQUEUE)) { @@ -3260,7 +3268,7 @@ of course. =head3 The special problem of life after fork - how is it possible? -Most uses of C<fork()> consist of forking, then some simple calls to set +Most uses of C<fork ()> consist of forking, then some simple calls to set up/change the process environment, followed by a call to C<exec()>. This sequence should be handled by libev without any problems. @@ -3660,9 +3668,9 @@ already been invoked. A common way around all these issues is to make sure that C<start_new_request> I<always> returns before the callback is invoked. If C<start_new_request> immediately knows the result, it can artificially -delay invoking the callback by e.g. using a C<prepare> or C<idle> watcher -for example, or more sneakily, by reusing an existing (stopped) watcher -and pushing it into the pending queue: +delay invoking the callback by using a C<prepare> or C<idle> watcher for +example, or more sneakily, by reusing an existing (stopped) watcher and +pushing it into the pending queue: ev_set_cb (watcher, callback); ev_feed_event (EV_A_ watcher, 0); @@ -3680,7 +3688,7 @@ This brings the problem of exiting - a callback might want to finish the main C<ev_run> call, but not the nested one (e.g. user clicked "Quit", but a modal "Are you sure?" dialog is still waiting), or just the nested one and not the main one (e.g. user clocked "Ok" in a modal dialog), or some -other combination: In these cases, C<ev_break> will not work alone. +other combination: In these cases, a simple C<ev_break> will not work. The solution is to maintain "break this loop" variable for each C<ev_run> invocation, and use a loop around C<ev_run> until the condition is @@ -3894,7 +3902,7 @@ files, F<my_ev.h> and F<my_ev.c> that include the respective libev files: // my_ev.h #define EV_CB_DECLARE(type) struct my_coro *cb; - #define EV_CB_INVOKE(watcher) switch_to ((watcher)->cb); + #define EV_CB_INVOKE(watcher) switch_to ((watcher)->cb) #include "../libev/ev.h" // my_ev.c @@ -3981,7 +3989,7 @@ you to use some convenience methods to start/stop watchers and also change the callback model to a model using method callbacks on objects. To use it, - + #include <ev++.h> This automatically includes F<ev.h> and puts all of its definitions (many @@ -4094,7 +4102,7 @@ Example: use a functor object as callback. ... } } - + myfunctor f; ev::io w; @@ -4619,9 +4627,10 @@ and makes libev faster. =item EV_NO_THREADS -If defined to be C<1>, libev will assume that it will never be called -from different threads, which is a stronger assumption than C<EV_NO_SMP>, -above. This reduces dependencies and makes libev faster. +If defined to be C<1>, libev will assume that it will never be called from +different threads (that includes signal handlers), which is a stronger +assumption than C<EV_NO_SMP>, above. This reduces dependencies and makes +libev faster. =item EV_ATOMIC_T @@ -5427,7 +5436,7 @@ new API early than late. =item C<EV_COMPAT3> backwards compatibility mechanism The backward compatibility mechanism can be controlled by -C<EV_COMPAT3>. See L</PREPROCESSOR SYMBOLS/MACROS> in the L</EMBEDDING> +C<EV_COMPAT3>. See L</"PREPROCESSOR SYMBOLS/MACROS"> in the L</EMBEDDING> section. =item C<ev_default_destroy> and C<ev_default_fork> have been removed diff --git a/third_party/libev/ev_epoll.c b/third_party/libev/ev_epoll.c index f5ad6188050563371eb7d6ae8bbaff6f45c2d619..7472b60e03050d418e36caf3b7849b7680c8d0c6 100644 --- a/third_party/libev/ev_epoll.c +++ b/third_party/libev/ev_epoll.c @@ -228,7 +228,10 @@ epoll_poll (EV_P_ ev_tstamp timeout) if (anfds [fd].emask & EV_EMASK_EPERM && events) fd_event (EV_A_ fd, events); else - epoll_eperms [i] = epoll_eperms [--epoll_epermcnt]; + { + epoll_eperms [i] = epoll_eperms [--epoll_epermcnt]; + anfds [fd].emask = 0; + } } } diff --git a/third_party/libev/ev_kqueue.c b/third_party/libev/ev_kqueue.c index 9faf65a660676867f4cb81eded3420193f9d923f..27def23d43d29b2121e9ba594f503225a2809b09 100644 --- a/third_party/libev/ev_kqueue.c +++ b/third_party/libev/ev_kqueue.c @@ -1,7 +1,7 @@ /* * libev kqueue backend * - * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de> + * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- diff --git a/third_party/libev/ev_vars.h b/third_party/libev/ev_vars.h index 5fd9c7a40fb22140b4e3edeb65ac6bf4ff991236..04d4db16f5cee31bdcb44888dce0a2c6c36c2575 100644 --- a/third_party/libev/ev_vars.h +++ b/third_party/libev/ev_vars.h @@ -1,7 +1,7 @@ /* * loop member variable declarations * - * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de> + * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- @@ -194,9 +194,10 @@ VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */ VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */ VARx(void *, userdata) +/* C++ doesn't support the ev_loop_callback typedef here. stinks. */ VAR (release_cb, void (*release_cb)(EV_P) EV_THROW) VAR (acquire_cb, void (*acquire_cb)(EV_P) EV_THROW) -VAR (invoke_cb , void (*invoke_cb) (EV_P)) +VAR (invoke_cb , ev_loop_callback invoke_cb) #endif #undef VARx diff --git a/third_party/libev/ev_win32.c b/third_party/libev/ev_win32.c index 9217af585c64602595081c660cedd4d3b160e6c0..d65634cce6bc498bb9ed8ab4e2adefa2f2be9a55 100644 --- a/third_party/libev/ev_win32.c +++ b/third_party/libev/ev_win32.c @@ -143,7 +143,7 @@ ev_pipe (int filedes [2]) #undef pipe #define pipe(filedes) ev_pipe (filedes) - + #define EV_HAVE_EV_TIME 1 ev_tstamp ev_time (void) diff --git a/third_party/libev/ev_wrap.h b/third_party/libev/ev_wrap.h index 4dd3d15fb6eb4eecccb866e0275fabc100651ca8..ad989ea7d5629884482079ec93bbe73211495e53 100644 --- a/third_party/libev/ev_wrap.h +++ b/third_party/libev/ev_wrap.h @@ -26,7 +26,6 @@ #define epoll_eperms ((loop)->epoll_eperms) #define epoll_eventmax ((loop)->epoll_eventmax) #define epoll_events ((loop)->epoll_events) -#define evfd ((loop)->evfd) #define evpipe ((loop)->evpipe) #define fdchangecnt ((loop)->fdchangecnt) #define fdchangemax ((loop)->fdchangemax) @@ -126,7 +125,6 @@ #undef epoll_eperms #undef epoll_eventmax #undef epoll_events -#undef evfd #undef evpipe #undef fdchangecnt #undef fdchangemax diff --git a/third_party/libev/libev.m4 b/third_party/libev/libev.m4 index 6fdb13f62271b55d105e19d0cc6964d9c5cd2c32..439fbde2c8d5a882052e849264e164708cebc099 100644 --- a/third_party/libev/libev.m4 +++ b/third_party/libev/libev.m4 @@ -1,12 +1,12 @@ dnl this file is part of libev, do not make local modifications dnl http://software.schmorp.de/pkg/libev -dnl libev support -AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h port.h poll.h sys/select.h sys/eventfd.h sys/signalfd.h) +dnl libev support +AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h port.h poll.h sys/select.h sys/eventfd.h sys/signalfd.h) AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select eventfd signalfd) -AC_CHECK_FUNCS(clock_gettime, [], [ +AC_CHECK_FUNCS(clock_gettime, [], [ dnl on linux, try syscall wrapper first if test $(uname) = Linux; then AC_MSG_CHECKING(for clock_gettime syscall) @@ -21,15 +21,15 @@ AC_CHECK_FUNCS(clock_gettime, [], [ [AC_MSG_RESULT(no)]) fi if test -z "$LIBEV_M4_AVOID_LIBRT" && test -z "$ac_have_clock_syscall"; then - AC_CHECK_LIB(rt, clock_gettime) + AC_CHECK_LIB(rt, clock_gettime) unset ac_cv_func_clock_gettime AC_CHECK_FUNCS(clock_gettime) fi ]) -AC_CHECK_FUNCS(nanosleep, [], [ +AC_CHECK_FUNCS(nanosleep, [], [ if test -z "$LIBEV_M4_AVOID_LIBRT"; then - AC_CHECK_LIB(rt, nanosleep) + AC_CHECK_LIB(rt, nanosleep) unset ac_cv_func_nanosleep AC_CHECK_FUNCS(nanosleep) fi