Browse Source

*** empty log message ***

Marc Alexander Lehmann 11 years ago
4 changed files with 33 additions and 18 deletions
  1. +5
  2. +7
  3. +2
  4. +19

+ 5
- 2
Changes View File

@ -1,6 +1,10 @@
Revision history for libev, a high-performance and full-featured event loop.
TODO: somehow unblock procmask?
- 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,7 +14,6 @@ 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

+ 7
- 4
ev.c View File

@ -1607,7 +1607,7 @@ loop_init (EV_P_ unsigned int flags)
fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
sigfd = flags & EVFLAG_NOSIGFD ? -1 : -2;
sigfd = flags & EVFLAG_SIGNALFD ? -2 : -1;
if (!(flags & 0x0000ffffU))
@ -2792,11 +2792,14 @@ ev_signal_stop (EV_P_ ev_signal *w)
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);

+ 2
- 1
ev.h View File

@ -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 */

+ 19
- 11
ev.pod View File

@ -372,13 +372,16 @@ I<inotify> API for it's C<ev_stat> watchers. Apart from debugging and
testing, this flag can be useful to conserve inotify file descriptors, as
otherwise each loop using C<ev_stat> watchers consumes one inotify handle.
When this flag is specified, then libev will not attempt to use the
I<signalfd> API for it's C<ev_signal> (and C<ev_child>) 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<signalfd> API for it's C<ev_signal> (and C<ev_child>) watchers. This API
delivers signals synchronously, which makes is both faster and might make
it possible to get the queued signal data.
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<EVBACKEND_SELECT> (value 1, portable select backend)
@ -2134,7 +2137,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<ev_check> watcher
and unblock them in an C<ev_prepare> 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<sigprocmask>) and the signal disposition
(C<sigaction>) are unspecified after starting a signal watcher (and after
@ -2154,10 +2157,15 @@ The simplest way to ensure that the signal mask is reset in the child is
to install a fork handler with C<pthread_atfork> 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<EVFLAG_NOSIGFD> 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<signalfd> API (C<EV_SIGNALFD>). While this reduces
the window of opportunity for problems, it will not go away, as libev
I<has> to modify the signal mask, at least temporarily.
So I can't stress this enough I<if you do not reset your signal mask
when you expect it to be empty, you have a race condition in your
program>. This is not a libev-specific thing, this is true for most event
=head3 Watcher-Specific Functions and Data Members