From 933a37cd283ec9b561970a96517a55b86ebee88d Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 4 Jan 2010 22:52:48 -0800 Subject: [PATCH] Upgrade libev to 3.9 --- deps/libev/Changes | 13 +++- deps/libev/configure.ac | 2 +- deps/libev/ev++.h | 5 ++ deps/libev/ev.3 | 157 ++++++++++++++++++++++++++++++++---------------- deps/libev/ev.c | 43 +++++++------ deps/libev/ev.h | 5 +- deps/libev/ev.pod | 86 ++++++++++++++++---------- deps/libev/ev_epoll.c | 2 + 8 files changed, 207 insertions(+), 106 deletions(-) diff --git a/deps/libev/Changes b/deps/libev/Changes index 39fc1bb..a9e0ac4 100644 --- a/deps/libev/Changes +++ b/deps/libev/Changes @@ -1,6 +1,11 @@ Revision history for libev, a high-performance and full-featured event loop. -TODO: somehow unblock procmask? +3.9 Thu Dec 31 07:59:59 CET 2009 + - signalfd is no longer used by default and has to be requested + explicitly - this means that easy to catch bugs become hard to + catch race conditions, but the users have spoken. + - point out the unspecified signal mask in the documentation, and + that this is a race condition regardless of EV_SIGNALFD. - backport inotify code to C89. - inotify file descriptors could leak into child processes. - ev_stat watchers could keep an errornous extra ref on the loop, @@ -10,13 +15,17 @@ TODO: somehow unblock procmask? symbols to make it easier for apps to do their own fd management. - support EV_IDLE_ENABLE being disabled in ev++.h (patch by Didier Spezia). - - point out the unspecified signal mask in the documentation. - take advantage of inotify_init1, if available, to set cloexec/nonblock on fd creation, to avoid races. - the signal handling pipe wasn't always initialised under windows (analysed by lekma). - changed minimum glibc requirement from glibc 2.9 to 2.7, for signalfd. + - add missing string.h include (Denis F. Latypoff). + - only replace ev_stat.prev when we detect an actual difference, + so prev is (almost) always different to attr. this might + have caused the probems with 04_stat.t. + - add ev::timer->remaining () method to C++ API. 3.8 Sun Aug 9 14:30:45 CEST 2009 - incompatible change: do not necessarily reset signal handler diff --git a/deps/libev/configure.ac b/deps/libev/configure.ac index 061bb39..8bb910d 100644 --- a/deps/libev/configure.ac +++ b/deps/libev/configure.ac @@ -1,7 +1,7 @@ AC_INIT AC_CONFIG_SRCDIR([ev_epoll.c]) -AM_INIT_AUTOMAKE(libev,3.8) dnl also update ev.h! +AM_INIT_AUTOMAKE(libev,3.9) dnl also update ev.h! AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE diff --git a/deps/libev/ev++.h b/deps/libev/ev++.h index fd2563f..73bcf32 100644 --- a/deps/libev/ev++.h +++ b/deps/libev/ev++.h @@ -644,6 +644,11 @@ namespace ev { { ev_timer_again (EV_A_ static_cast(this)); } + + ev_tstamp remaining () + { + return ev_timer_remaining (EV_A_ static_cast(this)); + } EV_END_WATCHER (timer, timer) #if EV_PERIODIC_ENABLE diff --git a/deps/libev/ev.3 b/deps/libev/ev.3 index 486ccc5..2c3c846 100644 --- a/deps/libev/ev.3 +++ b/deps/libev/ev.3 @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "LIBEV 3" -.TH LIBEV 3 "2009-07-27" "libev-3.8" "libev - high performance full featured event loop" +.TH LIBEV 3 "2009-12-31" "libev-3.9" "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 @@ -248,7 +248,7 @@ configuration will be described, which supports multiple event loops. For more info about various configuration options please have a look at \&\fB\s-1EMBED\s0\fR section in this manual. If libev was configured without support for multiple event loops, then all functions taking an initial argument of -name \f(CW\*(C`loop\*(C'\fR (which is always of type \f(CW\*(C`ev_loop *\*(C'\fR) will not have +name \f(CW\*(C`loop\*(C'\fR (which is always of type \f(CW\*(C`struct ev_loop *\*(C'\fR) will not have this argument. .SS "\s-1TIME\s0 \s-1REPRESENTATION\s0" .IX Subsection "TIME REPRESENTATION" @@ -488,14 +488,19 @@ When this flag is specified, then libev will not attempt to use the \&\fIinotify\fR \s-1API\s0 for it's \f(CW\*(C`ev_stat\*(C'\fR watchers. Apart from debugging and testing, this flag can be useful to conserve inotify file descriptors, as otherwise each loop using \f(CW\*(C`ev_stat\*(C'\fR watchers consumes one inotify handle. -.ie n .IP """EVFLAG_NOSIGNALFD""" 4 -.el .IP "\f(CWEVFLAG_NOSIGNALFD\fR" 4 -.IX Item "EVFLAG_NOSIGNALFD" -When this flag is specified, then libev will not attempt to use the -\&\fIsignalfd\fR \s-1API\s0 for it's \f(CW\*(C`ev_signal\*(C'\fR (and \f(CW\*(C`ev_child\*(C'\fR) watchers. This is -probably only useful to work around any bugs in libev. Consequently, this -flag might go away once the signalfd functionality is considered stable, -so it's useful mostly in environment variables and not in program code. +.ie n .IP """EVFLAG_SIGNALFD""" 4 +.el .IP "\f(CWEVFLAG_SIGNALFD\fR" 4 +.IX Item "EVFLAG_SIGNALFD" +When this flag is specified, then libev will attempt to use the +\&\fIsignalfd\fR \s-1API\s0 for it's \f(CW\*(C`ev_signal\*(C'\fR (and \f(CW\*(C`ev_child\*(C'\fR) watchers. This \s-1API\s0 +delivers signals synchronously, which makes it both faster and might make +it possible to get the queued signal data. It can also simplify signal +handling with threads, as long as you properly block signals in your +threads that are not interested in handling them. +.Sp +Signalfd will not be used by default as this changes your signal mask, and +there are a lot of shoddy libraries and programs (glib's threadpool for +example) that can't properly initialise their signal masks. .ie n .IP """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)" @@ -530,6 +535,9 @@ This backend maps \f(CW\*(C`EV_READ\*(C'\fR to \f(CW\*(C`POLLIN | POLLERR | POLL .ie n .IP """EVBACKEND_EPOLL"" (value 4, Linux)" 4 .el .IP "\f(CWEVBACKEND_EPOLL\fR (value 4, Linux)" 4 .IX Item "EVBACKEND_EPOLL (value 4, Linux)" +Use the linux-specific \fIepoll\fR\|(7) interface (for both pre\- and post\-2.6.9 +kernels). +.Sp For few fds, this backend is a bit little slower than poll and select, but it scales phenomenally better. While poll and select usually scale like O(total_fds) where n is the total number of fds (or the highest fd), @@ -716,7 +724,7 @@ as signal and child watchers) would need to be stopped manually. In general it is not advisable to call this function except in the rare occasion where you really need to free e.g. the signal handling pipe fds. If you need dynamically allocated loops it is better to use -\&\f(CW\*(C`ev_loop_new\*(C'\fR and \f(CW\*(C`ev_loop_destroy\*(C'\fR). +\&\f(CW\*(C`ev_loop_new\*(C'\fR and \f(CW\*(C`ev_loop_destroy\*(C'\fR. .IP "ev_loop_destroy (loop)" 4 .IX Item "ev_loop_destroy (loop)" Like \f(CW\*(C`ev_default_destroy\*(C'\fR, but destroys an event loop created by an @@ -823,8 +831,8 @@ event loop time (see \f(CW\*(C`ev_now_update\*(C'\fR). .IP "ev_loop (loop, int flags)" 4 .IX Item "ev_loop (loop, int flags)" Finally, this is it, the event handler. This function usually is called -after you initialised all your watchers and you want to start handling -events. +after you have initialised all your watchers and you want to start +handling events. .Sp If the flags argument is specified as \f(CW0\fR, it will not return until either no event watchers are active anymore or \f(CW\*(C`ev_unloop\*(C'\fR was called. @@ -912,9 +920,10 @@ Ref/unref can be used to add or remove a reference count on the event loop: Every watcher keeps one reference, and as long as the reference count is nonzero, \f(CW\*(C`ev_loop\*(C'\fR will not return on its own. .Sp -If you have a watcher you never unregister that should not keep \f(CW\*(C`ev_loop\*(C'\fR -from returning, call \fIev_unref()\fR after starting, and \fIev_ref()\fR before -stopping it. +This is useful when you have a watcher that you never intend to +unregister, but that nevertheless should not keep \f(CW\*(C`ev_loop\*(C'\fR from +returning. In such a case, call \f(CW\*(C`ev_unref\*(C'\fR after starting, and \f(CW\*(C`ev_ref\*(C'\fR +before stopping it. .Sp As an example, libev itself uses this for its internal signal pipe: It is not visible to the libev user and should not keep \f(CW\*(C`ev_loop\*(C'\fR from @@ -1042,7 +1051,7 @@ While event loop modifications are allowed between invocations of \&\f(CW\*(C`release\*(C'\fR and \f(CW\*(C`acquire\*(C'\fR (that's their only purpose after all), no modifications done will affect the event loop, i.e. adding watchers will have no effect on the set of file descriptors being watched, or the time -waited. USe an \f(CW\*(C`ev_async\*(C'\fR watcher to wake up \f(CW\*(C`ev_loop\*(C'\fR when you want it +waited. Use an \f(CW\*(C`ev_async\*(C'\fR watcher to wake up \f(CW\*(C`ev_loop\*(C'\fR when you want it to take note of any changes you made. .Sp In theory, threads executing \f(CW\*(C`ev_loop\*(C'\fR will be async-cancel safe between @@ -1247,9 +1256,9 @@ Example: Initialise an \f(CW\*(C`ev_io\*(C'\fR watcher in two steps. \& ev_init (&w, my_cb); \& ev_io_set (&w, STDIN_FILENO, EV_READ); .Ve -.ie n .IP """ev_TYPE_set"" (ev_TYPE *, [args])" 4 -.el .IP "\f(CWev_TYPE_set\fR (ev_TYPE *, [args])" 4 -.IX Item "ev_TYPE_set (ev_TYPE *, [args])" +.ie n .IP """ev_TYPE_set"" (ev_TYPE *watcher, [args])" 4 +.el .IP "\f(CWev_TYPE_set\fR (ev_TYPE *watcher, [args])" 4 +.IX Item "ev_TYPE_set (ev_TYPE *watcher, [args])" This macro initialises the type-specific parts of a watcher. You need to call \f(CW\*(C`ev_init\*(C'\fR at least once before you call this macro, but you can call \f(CW\*(C`ev_TYPE_set\*(C'\fR any number of times. You must not, however, call this @@ -1272,9 +1281,9 @@ Example: Initialise and set an \f(CW\*(C`ev_io\*(C'\fR watcher in one step. .Vb 1 \& ev_io_init (&w, my_cb, STDIN_FILENO, EV_READ); .Ve -.ie n .IP """ev_TYPE_start"" (loop *, ev_TYPE *watcher)" 4 -.el .IP "\f(CWev_TYPE_start\fR (loop *, ev_TYPE *watcher)" 4 -.IX Item "ev_TYPE_start (loop *, ev_TYPE *watcher)" +.ie n .IP """ev_TYPE_start"" (loop, ev_TYPE *watcher)" 4 +.el .IP "\f(CWev_TYPE_start\fR (loop, ev_TYPE *watcher)" 4 +.IX Item "ev_TYPE_start (loop, ev_TYPE *watcher)" Starts (activates) the given watcher. Only active watchers will receive events. If the watcher is already active nothing will happen. .Sp @@ -1284,9 +1293,9 @@ whole section. .Vb 1 \& ev_io_start (EV_DEFAULT_UC, &w); .Ve -.ie n .IP """ev_TYPE_stop"" (loop *, ev_TYPE *watcher)" 4 -.el .IP "\f(CWev_TYPE_stop\fR (loop *, ev_TYPE *watcher)" 4 -.IX Item "ev_TYPE_stop (loop *, ev_TYPE *watcher)" +.ie n .IP """ev_TYPE_stop"" (loop, ev_TYPE *watcher)" 4 +.el .IP "\f(CWev_TYPE_stop\fR (loop, ev_TYPE *watcher)" 4 +.IX Item "ev_TYPE_stop (loop, ev_TYPE *watcher)" Stops the given watcher if active, and clears the pending status (whether the watcher was active or not). .Sp @@ -1315,8 +1324,8 @@ Returns the callback currently set on the watcher. .IX Item "ev_cb_set (ev_TYPE *watcher, callback)" Change the callback. You can change the callback at virtually any time (modulo threads). -.IP "ev_set_priority (ev_TYPE *watcher, priority)" 4 -.IX Item "ev_set_priority (ev_TYPE *watcher, priority)" +.IP "ev_set_priority (ev_TYPE *watcher, int priority)" 4 +.IX Item "ev_set_priority (ev_TYPE *watcher, int priority)" .PD 0 .IP "int ev_priority (ev_TYPE *watcher)" 4 .IX Item "int ev_priority (ev_TYPE *watcher)" @@ -1356,6 +1365,19 @@ watcher isn't pending it does nothing and returns \f(CW0\fR. .Sp Sometimes it can be useful to \*(L"poll\*(R" a watcher instead of waiting for its callback to be invoked, which can be accomplished with this function. +.IP "ev_feed_event (loop, ev_TYPE *watcher, int revents)" 4 +.IX Item "ev_feed_event (loop, ev_TYPE *watcher, int revents)" +Feeds the given event set into the event loop, as if the specified event +had happened for the specified watcher (which must be a pointer to an +initialised but not necessarily started event watcher). Obviously you must +not free the watcher as long as it has pending events. +.Sp +Stopping the watcher, letting libev invoke it, or calling +\&\f(CW\*(C`ev_clear_pending\*(C'\fR will clear the pending event, even if the watcher was +not started in the first place. +.Sp +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. .SS "\s-1ASSOCIATING\s0 \s-1CUSTOM\s0 \s-1DATA\s0 \s-1WITH\s0 A \s-1WATCHER\s0" .IX Subsection "ASSOCIATING CUSTOM DATA WITH A WATCHER" Each watcher has, by default, a member \f(CW\*(C`void *data\*(C'\fR that you can change @@ -1976,8 +1998,8 @@ If the timer is repeating, either start it if necessary (with the .Sp This sounds a bit complicated, see \*(L"Be smart about timeouts\*(R", above, for a usage example. -.IP "ev_timer_remaining (loop, ev_timer *)" 4 -.IX Item "ev_timer_remaining (loop, ev_timer *)" +.IP "ev_tstamp ev_timer_remaining (loop, ev_timer *)" 4 +.IX Item "ev_tstamp ev_timer_remaining (loop, ev_timer *)" Returns the remaining time until a timer fires. If the timer is active, then this time is relative to the current event loop time, otherwise it's the timeout value currently configured. @@ -2251,17 +2273,42 @@ 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). .PP -Both the signal mask state (\f(CW\*(C`sigprocmask\*(C'\fR) and the signal handler state -(\f(CW\*(C`sigaction\*(C'\fR) are unspecified after starting a signal watcher (and after -sotpping it again), that is, libev might or might not block the signal, -and might or might not set or restore the installed signal handler. -.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 not be unduly interrupted. If you have a problem with system calls getting interrupted by signals you can block all signals in an \f(CW\*(C`ev_check\*(C'\fR watcher and unblock them in an \f(CW\*(C`ev_prepare\*(C'\fR watcher. .PP +\fIThe special problem of inheritance over fork/execve/pthread_create\fR +.IX Subsection "The special problem of inheritance over fork/execve/pthread_create" +.PP +Both the signal mask (\f(CW\*(C`sigprocmask\*(C'\fR) and the signal disposition +(\f(CW\*(C`sigaction\*(C'\fR) are unspecified after starting a signal watcher (and after +stopping it again), that is, libev might or might not block the signal, +and might or might not set or restore the installed signal handler. +.PP +While this does not matter for the signal disposition (libev never +sets signals to \f(CW\*(C`SIG_IGN\*(C'\fR, so handlers will be reset to \f(CW\*(C`SIG_DFL\*(C'\fR on +\&\f(CW\*(C`execve\*(C'\fR), this matters for the signal mask: many programs do not expect +certain signals to be blocked. +.PP +This means that before calling \f(CW\*(C`exec\*(C'\fR (from the child) you should reset +the signal mask to whatever \*(L"default\*(R" you expect (all clear is a good +choice usually). +.PP +The simplest way to ensure that the signal mask is reset in the child is +to install a fork handler with \f(CW\*(C`pthread_atfork\*(C'\fR that resets it. That will +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 +the window of opportunity for problems, it will not go away, as libev +\&\fIhas\fR to modify the signal mask, at least temporarily. +.PP +So I can't stress this enough: \fIIf you do not reset your signal mask when +you expect it to be empty, you have a race condition in your code\fR. This +is not a libev-specific thing, this is true for most event libraries. +.PP \fIWatcher-Specific Functions and Data Members\fR .IX Subsection "Watcher-Specific Functions and Data Members" .IP "ev_signal_init (ev_signal *, callback, int signum)" 4 @@ -3087,7 +3134,8 @@ just the default loop. \&\f(CW\*(C`ev_async\*(C'\fR does not support queueing of data in any way. The reason is that the author does not know of a simple (or any) algorithm for a multiple-writer-single-reader queue that works in all cases and doesn't -need elaborate support such as pthreads. +need elaborate support such as pthreads or unportable memory access +semantics. .PP That means that if you want to queue data, you have to provide your own queue. But at least I can tell you how to implement locking around your @@ -3242,17 +3290,12 @@ Example: wait up to ten seconds for data to appear on \s-1STDIN_FILENO\s0. \& \& ev_once (STDIN_FILENO, EV_READ, 10., stdin_ready, 0); .Ve -.IP "ev_feed_event (struct ev_loop *, watcher *, int revents)" 4 -.IX Item "ev_feed_event (struct ev_loop *, watcher *, int revents)" -Feeds the given event set into the event loop, as if the specified event -had happened for the specified watcher (which must be a pointer to an -initialised but not necessarily started event watcher). -.IP "ev_feed_fd_event (struct ev_loop *, int fd, int revents)" 4 -.IX Item "ev_feed_fd_event (struct ev_loop *, int fd, int revents)" +.IP "ev_feed_fd_event (loop, int fd, int revents)" 4 +.IX Item "ev_feed_fd_event (loop, int fd, int revents)" Feed an event on the given fd, as if a file descriptor backend detected the given events it. -.IP "ev_feed_signal_event (struct ev_loop *loop, int signum)" 4 -.IX Item "ev_feed_signal_event (struct ev_loop *loop, int signum)" +.IP "ev_feed_signal_event (loop, int signum)" 4 +.IX Item "ev_feed_signal_event (loop, int signum)" Feed an event as if the given signal occurred (\f(CW\*(C`loop\*(C'\fR must be the default loop!). .SH "LIBEVENT EMULATION" @@ -3331,8 +3374,8 @@ All of those classes have these methods: .IP "ev::TYPE::TYPE ()" 4 .IX Item "ev::TYPE::TYPE ()" .PD 0 -.IP "ev::TYPE::TYPE (struct ev_loop *)" 4 -.IX Item "ev::TYPE::TYPE (struct ev_loop *)" +.IP "ev::TYPE::TYPE (loop)" 4 +.IX Item "ev::TYPE::TYPE (loop)" .IP "ev::TYPE::~TYPE" 4 .IX Item "ev::TYPE::~TYPE" .PD @@ -3421,8 +3464,8 @@ Example: Use a plain function as callback. \& static void io_cb (ev::io &w, int revents) { } \& iow.set (); .Ve -.IP "w\->set (struct ev_loop *)" 4 -.IX Item "w->set (struct ev_loop *)" +.IP "w\->set (loop)" 4 +.IX Item "w->set (loop)" Associates a different \f(CW\*(C`struct ev_loop\*(C'\fR with this watcher. You can only do this when the watcher is inactive (and not pending either). .IP "w\->set ([arguments])" 4 @@ -3771,13 +3814,25 @@ be used is the winsock select). This means that it will call \&\f(CW\*(C`_get_osfhandle\*(C'\fR on the fd to convert it to an \s-1OS\s0 handle. Otherwise, it is assumed that all these functions actually work on fds, even on win32. Should not be defined on non\-win32 platforms. -.IP "\s-1EV_FD_TO_WIN32_HANDLE\s0" 4 -.IX Item "EV_FD_TO_WIN32_HANDLE" +.IP "\s-1EV_FD_TO_WIN32_HANDLE\s0(fd)" 4 +.IX Item "EV_FD_TO_WIN32_HANDLE(fd)" If \f(CW\*(C`EV_SELECT_IS_WINSOCKET\*(C'\fR is enabled, then libev needs a way to map file descriptors to socket handles. When not defining this symbol (the default), then libev will call \f(CW\*(C`_get_osfhandle\*(C'\fR, which is usually correct. In some cases, programs use their own file descriptor management, in which case they can provide this function to map fds to socket handles. +.IP "\s-1EV_WIN32_HANDLE_TO_FD\s0(handle)" 4 +.IX Item "EV_WIN32_HANDLE_TO_FD(handle)" +If \f(CW\*(C`EV_SELECT_IS_WINSOCKET\*(C'\fR then libev maps handles to file descriptors +using the standard \f(CW\*(C`_open_osfhandle\*(C'\fR function. For programs implementing +their own fd to handle mapping, overwriting this function makes it easier +to do so. This can be done by defining this macro to an appropriate value. +.IP "\s-1EV_WIN32_CLOSE_FD\s0(fd)" 4 +.IX Item "EV_WIN32_CLOSE_FD(fd)" +If programs implement their own fd to handle mapping on win32, then this +macro can be used to override the \f(CW\*(C`close\*(C'\fR function, useful to unregister +file descriptors again. Note that the replacement function has to close +the underlying \s-1OS\s0 handle. .IP "\s-1EV_USE_POLL\s0" 4 .IX Item "EV_USE_POLL" If defined to be \f(CW1\fR, libev will compile in support for the \f(CW\*(C`poll\*(C'\fR(2) diff --git a/deps/libev/ev.c b/deps/libev/ev.c index cbbf47e..ccd202b 100644 --- a/deps/libev/ev.c +++ b/deps/libev/ev.c @@ -155,6 +155,7 @@ extern "C" { #include #include +#include #include #include @@ -1606,7 +1607,7 @@ loop_init (EV_P_ unsigned int flags) fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2; #endif #if EV_USE_SIGNALFD - sigfd = flags & EVFLAG_NOSIGFD ? -1 : -2; + sigfd = flags & EVFLAG_SIGNALFD ? -2 : -1; #endif if (!(flags & 0x0000ffffU)) @@ -2791,11 +2792,14 @@ ev_signal_stop (EV_P_ ev_signal *w) #if EV_USE_SIGNALFD if (sigfd >= 0) { - sigprocmask (SIG_UNBLOCK, &sigfd_set, 0);//D + sigset_t ss; + + sigemptyset (&ss); + sigaddset (&ss, w->signum); sigdelset (&sigfd_set, w->signum); + signalfd (sigfd, &sigfd_set, 0); - sigprocmask (SIG_BLOCK, &sigfd_set, 0);//D - /*TODO: maybe unblock signal? */ + sigprocmask (SIG_UNBLOCK, &ss, 0); } else #endif @@ -3102,25 +3106,28 @@ stat_timer_cb (EV_P_ ev_timer *w_, int revents) { ev_stat *w = (ev_stat *)(((char *)w_) - offsetof (ev_stat, timer)); - /* we copy this here each the time so that */ - /* prev has the old value when the callback gets invoked */ - w->prev = w->attr; + ev_statdata prev = w->attr; ev_stat_stat (EV_A_ w); /* memcmp doesn't work on netbsd, they.... do stuff to their struct stat */ if ( - w->prev.st_dev != w->attr.st_dev - || w->prev.st_ino != w->attr.st_ino - || w->prev.st_mode != w->attr.st_mode - || w->prev.st_nlink != w->attr.st_nlink - || w->prev.st_uid != w->attr.st_uid - || w->prev.st_gid != w->attr.st_gid - || w->prev.st_rdev != w->attr.st_rdev - || w->prev.st_size != w->attr.st_size - || w->prev.st_atime != w->attr.st_atime - || w->prev.st_mtime != w->attr.st_mtime - || w->prev.st_ctime != w->attr.st_ctime + prev.st_dev != w->attr.st_dev + || prev.st_ino != w->attr.st_ino + || prev.st_mode != w->attr.st_mode + || prev.st_nlink != w->attr.st_nlink + || prev.st_uid != w->attr.st_uid + || prev.st_gid != w->attr.st_gid + || prev.st_rdev != w->attr.st_rdev + || prev.st_size != w->attr.st_size + || prev.st_atime != w->attr.st_atime + || prev.st_mtime != w->attr.st_mtime + || prev.st_ctime != w->attr.st_ctime ) { + /* we only update w->prev on actual differences */ + /* in case we test more often than invoke the callback, */ + /* to ensure that prev is always different to attr */ + w->prev = prev; + #if EV_USE_INOTIFY if (fs_fd >= 0) { diff --git a/deps/libev/ev.h b/deps/libev/ev.h index e6af59a..c7c44ff 100644 --- a/deps/libev/ev.h +++ b/deps/libev/ev.h @@ -163,7 +163,7 @@ struct ev_loop; #endif #define EV_VERSION_MAJOR 3 -#define EV_VERSION_MINOR 8 +#define EV_VERSION_MINOR 9 #ifndef EV_CB_DECLARE # define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents); @@ -406,7 +406,8 @@ union ev_any_watcher #define EVFLAG_FORKCHECK 0x02000000U /* check for a fork in each iteration */ /* debugging/feature disable */ #define EVFLAG_NOINOTIFY 0x00100000U /* do not attempt to use inotify */ -#define EVFLAG_NOSIGFD 0x00200000U /* do not attempt to use signalfd */ +#define EVFLAG_NOSIGFD 0 /* compatibility to pre-3.9 */ +#define EVFLAG_SIGNALFD 0x00200000U /* attempt to use signalfd */ /* method bits to be ored together */ #define EVBACKEND_SELECT 0x00000001U /* about anywhere */ #define EVBACKEND_POLL 0x00000002U /* !win */ diff --git a/deps/libev/ev.pod b/deps/libev/ev.pod index 4e34827..0fe8881 100644 --- a/deps/libev/ev.pod +++ b/deps/libev/ev.pod @@ -120,7 +120,7 @@ configuration will be described, which supports multiple event loops. For more info about various configuration options please have a look at B section in this manual. If libev was configured without support for multiple event loops, then all functions taking an initial argument of -name C (which is always of type C) will not have +name C (which is always of type C) will not have this argument. =head2 TIME REPRESENTATION @@ -372,13 +372,18 @@ I API for it's C watchers. Apart from debugging and testing, this flag can be useful to conserve inotify file descriptors, as otherwise each loop using C watchers consumes one inotify handle. -=item C +=item C -When this flag is specified, then libev will not attempt to use the -I API for it's C (and C) watchers. This is -probably only useful to work around any bugs in libev. Consequently, this -flag might go away once the signalfd functionality is considered stable, -so it's useful mostly in environment variables and not in program code. +When this flag is specified, then libev will attempt to use the +I API for it's C (and C) watchers. This API +delivers signals synchronously, which makes it both faster and might make +it possible to get the queued signal data. It can also simplify signal +handling with threads, as long as you properly block signals in your +threads that are not interested in handling them. + +Signalfd will not be used by default as this changes your signal mask, and +there are a lot of shoddy libraries and programs (glib's threadpool for +example) that can't properly initialise their signal masks. =item C (value 1, portable select backend) @@ -413,6 +418,9 @@ C to C. =item C (value 4, Linux) +Use the linux-specific epoll(7) interface (for both pre- and post-2.6.9 +kernels). + For few fds, this backend is a bit little slower than poll and select, but it scales phenomenally better. While poll and select usually scale like O(total_fds) where n is the total number of fds (or the highest fd), @@ -791,9 +799,10 @@ Ref/unref can be used to add or remove a reference count on the event loop: Every watcher keeps one reference, and as long as the reference count is nonzero, C will not return on its own. -If you have a watcher you never unregister that should not keep C -from returning, call ev_unref() after starting, and ev_ref() before -stopping it. +This is useful when you have a watcher that you never intend to +unregister, but that nevertheless should not keep C from +returning. In such a case, call C after starting, and C +before stopping it. As an example, libev itself uses this for its internal signal pipe: It is not visible to the libev user and should not keep C from @@ -918,7 +927,7 @@ While event loop modifications are allowed between invocations of C and C (that's their only purpose after all), no modifications done will affect the event loop, i.e. adding watchers will have no effect on the set of file descriptors being watched, or the time -waited. USe an C watcher to wake up C when you want it +waited. Use an C watcher to wake up C when you want it to take note of any changes you made. In theory, threads executing C will be async-cancel safe between @@ -1125,7 +1134,7 @@ Example: Initialise an C watcher in two steps. ev_init (&w, my_cb); ev_io_set (&w, STDIN_FILENO, EV_READ); -=item C (ev_TYPE *, [args]) +=item C (ev_TYPE *watcher, [args]) This macro initialises the type-specific parts of a watcher. You need to call C at least once before you call this macro, but you can @@ -1148,7 +1157,7 @@ Example: Initialise and set an C watcher in one step. ev_io_init (&w, my_cb, STDIN_FILENO, EV_READ); -=item C (loop *, ev_TYPE *watcher) +=item C (loop, ev_TYPE *watcher) Starts (activates) the given watcher. Only active watchers will receive events. If the watcher is already active nothing will happen. @@ -1158,7 +1167,7 @@ whole section. ev_io_start (EV_DEFAULT_UC, &w); -=item C (loop *, ev_TYPE *watcher) +=item C (loop, ev_TYPE *watcher) Stops the given watcher if active, and clears the pending status (whether the watcher was active or not). @@ -1193,7 +1202,7 @@ Returns the callback currently set on the watcher. Change the callback. You can change the callback at virtually any time (modulo threads). -=item ev_set_priority (ev_TYPE *watcher, priority) +=item ev_set_priority (ev_TYPE *watcher, int priority) =item int ev_priority (ev_TYPE *watcher) @@ -1235,6 +1244,20 @@ watcher isn't pending it does nothing and returns C<0>. Sometimes it can be useful to "poll" a watcher instead of waiting for its callback to be invoked, which can be accomplished with this function. +=item ev_feed_event (loop, ev_TYPE *watcher, int revents) + +Feeds the given event set into the event loop, as if the specified event +had happened for the specified watcher (which must be a pointer to an +initialised but not necessarily started event watcher). Obviously you must +not free the watcher as long as it has pending events. + +Stopping the watcher, letting libev invoke it, or calling +C will clear the pending event, even if the watcher was +not started in the first place. + +See also C and C for related +functions that do not need a watcher. + =back @@ -1839,7 +1862,7 @@ C value), or reset the running timer to the C value. This sounds a bit complicated, see L, above, for a usage example. -=item ev_timer_remaining (loop, ev_timer *) +=item ev_tstamp ev_timer_remaining (loop, ev_timer *) Returns the remaining time until a timer fires. If the timer is active, then this time is relative to the current event loop time, otherwise it's @@ -2116,7 +2139,7 @@ not be unduly interrupted. If you have a problem with system calls getting interrupted by signals you can block all signals in an C watcher and unblock them in an C watcher. -=head3 The special problem of inheritance over execve +=head3 The special problem of inheritance over fork/execve/pthread_create Both the signal mask (C) and the signal disposition (C) are unspecified after starting a signal watcher (and after @@ -2136,10 +2159,14 @@ The simplest way to ensure that the signal mask is reset in the child is to install a fork handler with C that resets it. That will catch fork calls done by libraries (such as the libc) as well. -In current versions of libev, you can also ensure that the signal mask is -not blocking any signals (except temporarily, so thread users watch out) -by specifying the C when creating the event loop. This -is not guaranteed for future versions, however. +In current versions of libev, the signal will not be blocked indefinitely +unless you use the C API (C). While this reduces +the window of opportunity for problems, it will not go away, as libev +I to modify the signal mask, at least temporarily. + +So I can't stress this enough: I. This +is not a libev-specific thing, this is true for most event libraries. =head3 Watcher-Specific Functions and Data Members @@ -2966,7 +2993,8 @@ just the default loop. C does not support queueing of data in any way. The reason is that the author does not know of a simple (or any) algorithm for a multiple-writer-single-reader queue that works in all cases and doesn't -need elaborate support such as pthreads. +need elaborate support such as pthreads or unportable memory access +semantics. That means that if you want to queue data, you have to provide your own queue. But at least I can tell you how to implement locking around your @@ -3134,18 +3162,12 @@ Example: wait up to ten seconds for data to appear on STDIN_FILENO. ev_once (STDIN_FILENO, EV_READ, 10., stdin_ready, 0); -=item ev_feed_event (struct ev_loop *, watcher *, int revents) - -Feeds the given event set into the event loop, as if the specified event -had happened for the specified watcher (which must be a pointer to an -initialised but not necessarily started event watcher). - -=item ev_feed_fd_event (struct ev_loop *, int fd, int revents) +=item ev_feed_fd_event (loop, int fd, int revents) Feed an event on the given fd, as if a file descriptor backend detected the given events it. -=item ev_feed_signal_event (struct ev_loop *loop, int signum) +=item ev_feed_signal_event (loop, int signum) Feed an event as if the given signal occurred (C must be the default loop!). @@ -3235,7 +3257,7 @@ All of those classes have these methods: =item ev::TYPE::TYPE () -=item ev::TYPE::TYPE (struct ev_loop *) +=item ev::TYPE::TYPE (loop) =item ev::TYPE::~TYPE @@ -3322,7 +3344,7 @@ Example: Use a plain function as callback. static void io_cb (ev::io &w, int revents) { } iow.set (); -=item w->set (struct ev_loop *) +=item w->set (loop) Associates a different C with this watcher. You can only do this when the watcher is inactive (and not pending either). diff --git a/deps/libev/ev_epoll.c b/deps/libev/ev_epoll.c index 04acd98..f7e3d60 100644 --- a/deps/libev/ev_epoll.c +++ b/deps/libev/ev_epoll.c @@ -161,6 +161,8 @@ epoll_poll (EV_P_ ev_tstamp timeout) ev->events = (want & EV_READ ? EPOLLIN : 0) | (want & EV_WRITE ? EPOLLOUT : 0); + /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */ + /* which is fortunately easy to do for us. */ if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) { postfork = 1; /* an error occured, recreate kernel state */ -- 2.7.4