Commit 29fc1110 authored by Denis Bilenko's avatar Denis Bilenko

update libev to latest CVS version

parent a297a4d2
...@@ -4,9 +4,12 @@ TODO: ev_loop_wakeup ...@@ -4,9 +4,12 @@ TODO: ev_loop_wakeup
TODO: EV_STANDALONE == NO_HASSEL (do not use clock_gettime in ev_standalone) TODO: EV_STANDALONE == NO_HASSEL (do not use clock_gettime in ev_standalone)
TODO: faq, process a thing in each iteration TODO: faq, process a thing in each iteration
TODO: dbeugging tips, ev_verify, ev_init twice 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: document the special problem of signals around fork.
TODO: ev_feed_child_event TODO: store pid for each signal
TODO: document file descriptor usage per loop
- destroying a non-default loop would stop the global waitpid - destroying a non-default loop would stop the global waitpid
watcher (Denis Bilenko). watcher (Denis Bilenko).
- queueing pending watchers of higher priority from a watcher now invokes - queueing pending watchers of higher priority from a watcher now invokes
...@@ -37,6 +40,12 @@ TODO: ev_feed_child_event ...@@ -37,6 +40,12 @@ TODO: ev_feed_child_event
works in all cases (unlike read/write/send/recv...). works in all cases (unlike read/write/send/recv...).
- try to detect signals around a fork faster (test program by - try to detect signals around a fork faster (test program by
Denis Bilenko). Denis Bilenko).
- work around recent glibc versions that leak memory in realloc.
- 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
on fork, at the cost of one extra fd.
4.11 Sat Feb 4 19:52:39 CET 2012 4.11 Sat Feb 4 19:52:39 CET 2012
- INCOMPATIBLE CHANGE: ev_timer_again now clears the pending status, as - INCOMPATIBLE CHANGE: ev_timer_again now clears the pending status, as
......
...@@ -1193,12 +1193,11 @@ ev_syserr (const char *msg) ...@@ -1193,12 +1193,11 @@ ev_syserr (const char *msg)
static void * static void *
ev_realloc_emul (void *ptr, long size) EV_THROW ev_realloc_emul (void *ptr, long size) EV_THROW
{ {
#if __GLIBC__
return realloc (ptr, size);
#else
/* some systems, notably openbsd and darwin, fail to properly /* some systems, notably openbsd and darwin, fail to properly
* implement realloc (x, 0) (as required by both ansi c-89 and * implement realloc (x, 0) (as required by both ansi c-89 and
* the single unix specification, so work around them here. * the single unix specification, so work around them here.
* recently, also (at least) fedora and debian started breaking it,
* despite documenting it otherwise.
*/ */
if (size) if (size)
...@@ -1206,7 +1205,6 @@ ev_realloc_emul (void *ptr, long size) EV_THROW ...@@ -1206,7 +1205,6 @@ ev_realloc_emul (void *ptr, long size) EV_THROW
free (ptr); free (ptr);
return 0; return 0;
#endif
} }
static void *(*alloc)(void *ptr, long size) EV_THROW = ev_realloc_emul; static void *(*alloc)(void *ptr, long size) EV_THROW = ev_realloc_emul;
...@@ -1871,28 +1869,41 @@ evpipe_init (EV_P) ...@@ -1871,28 +1869,41 @@ evpipe_init (EV_P)
{ {
if (!ev_is_active (&pipe_w)) if (!ev_is_active (&pipe_w))
{ {
int fds [2];
# if EV_USE_EVENTFD # if EV_USE_EVENTFD
evfd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC); fds [0] = -1;
if (evfd < 0 && errno == EINVAL) fds [1] = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
evfd = eventfd (0, 0); if (fds [1] < 0 && errno == EINVAL)
fds [1] = eventfd (0, 0);
if (evfd >= 0) if (fds [1] < 0)
# endif
{ {
evpipe [0] = -1; while (pipe (fds))
fd_intern (evfd); /* doing it twice doesn't hurt */ ev_syserr ("(libev) error creating signal/async pipe");
ev_io_set (&pipe_w, evfd, EV_READ);
fd_intern (fds [0]);
} }
fd_intern (fds [1]);
evpipe [0] = fds [0];
if (evpipe [1] < 0)
evpipe [1] = fds [1]; /* first call, set write fd */
else else
# endif
{ {
while (pipe (evpipe)) /* on subsequent calls, do not change evpipe [1] */
ev_syserr ("(libev) error creating signal/async pipe"); /* so that evpipe_write can always rely on its value. */
/* this branch does not do anything sensible on windows, */
/* so must not be executed on windows */
fd_intern (evpipe [0]); dup2 (fds [1], evpipe [1]);
fd_intern (evpipe [1]); close (fds [1]);
ev_io_set (&pipe_w, evpipe [0], EV_READ);
} }
ev_io_set (&pipe_w, evpipe [0] < 0 ? evpipe [1] : evpipe [0], EV_READ);
ev_io_start (EV_A_ &pipe_w); ev_io_start (EV_A_ &pipe_w);
ev_unref (EV_A); /* watcher should not keep loop alive */ ev_unref (EV_A); /* watcher should not keep loop alive */
} }
...@@ -1923,10 +1934,10 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag) ...@@ -1923,10 +1934,10 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag)
old_errno = errno; /* save errno because write will clobber it */ old_errno = errno; /* save errno because write will clobber it */
#if EV_USE_EVENTFD #if EV_USE_EVENTFD
if (evfd >= 0) if (evpipe [0] < 0)
{ {
uint64_t counter = 1; uint64_t counter = 1;
write (evfd, &counter, sizeof (uint64_t)); write (evpipe [1], &counter, sizeof (uint64_t));
} }
else else
#endif #endif
...@@ -1956,10 +1967,10 @@ pipecb (EV_P_ ev_io *iow, int revents) ...@@ -1956,10 +1967,10 @@ pipecb (EV_P_ ev_io *iow, int revents)
if (revents & EV_READ) if (revents & EV_READ)
{ {
#if EV_USE_EVENTFD #if EV_USE_EVENTFD
if (evfd >= 0) if (evpipe [0] < 0)
{ {
uint64_t counter; uint64_t counter;
read (evfd, &counter, sizeof (uint64_t)); read (evpipe [1], &counter, sizeof (uint64_t));
} }
else else
#endif #endif
...@@ -2025,9 +2036,6 @@ ev_feed_signal (int signum) EV_THROW ...@@ -2025,9 +2036,6 @@ ev_feed_signal (int signum) EV_THROW
return; return;
#endif #endif
if (!ev_active (&pipe_w))
return;
signals [signum - 1].pending = 1; signals [signum - 1].pending = 1;
evpipe_write (EV_A_ &sig_pending); evpipe_write (EV_A_ &sig_pending);
} }
...@@ -2047,7 +2055,7 @@ ev_feed_signal_event (EV_P_ int signum) EV_THROW ...@@ -2047,7 +2055,7 @@ ev_feed_signal_event (EV_P_ int signum) EV_THROW
{ {
WL w; WL w;
if (expect_false (signum <= 0 || signum > EV_NSIG)) if (expect_false (signum <= 0 || signum >= EV_NSIG))
return; return;
--signum; --signum;
...@@ -2355,6 +2363,8 @@ loop_init (EV_P_ unsigned int flags) EV_THROW ...@@ -2355,6 +2363,8 @@ loop_init (EV_P_ unsigned int flags) EV_THROW
#endif #endif
pipe_write_skipped = 0; pipe_write_skipped = 0;
pipe_write_wanted = 0; pipe_write_wanted = 0;
evpipe [0] = -1;
evpipe [1] = -1;
#if EV_USE_INOTIFY #if EV_USE_INOTIFY
fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2; fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
#endif #endif
...@@ -2427,16 +2437,8 @@ ev_loop_destroy (EV_P) ...@@ -2427,16 +2437,8 @@ ev_loop_destroy (EV_P)
/*ev_ref (EV_A);*/ /*ev_ref (EV_A);*/
/*ev_io_stop (EV_A_ &pipe_w);*/ /*ev_io_stop (EV_A_ &pipe_w);*/
#if EV_USE_EVENTFD if (evpipe [0] >= 0) EV_WIN32_CLOSE_FD (evpipe [0]);
if (evfd >= 0) if (evpipe [1] >= 0) EV_WIN32_CLOSE_FD (evpipe [1]);
close (evfd);
#endif
if (evpipe [0] >= 0)
{
EV_WIN32_CLOSE_FD (evpipe [0]);
EV_WIN32_CLOSE_FD (evpipe [1]);
}
} }
#if EV_USE_SIGNALFD #if EV_USE_SIGNALFD
...@@ -2532,6 +2534,7 @@ loop_fork (EV_P) ...@@ -2532,6 +2534,7 @@ loop_fork (EV_P)
infy_fork (EV_A); infy_fork (EV_A);
#endif #endif
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
if (ev_is_active (&pipe_w)) if (ev_is_active (&pipe_w))
{ {
/* pipe_write_wanted must be false now, so modifying fd vars should be safe */ /* pipe_write_wanted must be false now, so modifying fd vars should be safe */
...@@ -2539,23 +2542,14 @@ loop_fork (EV_P) ...@@ -2539,23 +2542,14 @@ loop_fork (EV_P)
ev_ref (EV_A); ev_ref (EV_A);
ev_io_stop (EV_A_ &pipe_w); ev_io_stop (EV_A_ &pipe_w);
#if EV_USE_EVENTFD
if (evfd >= 0)
close (evfd);
#endif
if (evpipe [0] >= 0) if (evpipe [0] >= 0)
{ EV_WIN32_CLOSE_FD (evpipe [0]);
EV_WIN32_CLOSE_FD (evpipe [0]);
EV_WIN32_CLOSE_FD (evpipe [1]);
}
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
evpipe_init (EV_A); evpipe_init (EV_A);
/* iterate over everything, in case we missed something before */ /* iterate over everything, in case we missed something before */
ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM); ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);
#endif
} }
#endif
postfork = 0; postfork = 0;
} }
......
...@@ -238,7 +238,7 @@ epoll_init (EV_P_ int flags) ...@@ -238,7 +238,7 @@ epoll_init (EV_P_ int flags)
#ifdef EPOLL_CLOEXEC #ifdef EPOLL_CLOEXEC
backend_fd = epoll_create1 (EPOLL_CLOEXEC); backend_fd = epoll_create1 (EPOLL_CLOEXEC);
if (backend_fd < 0) if (backend_fd < 0 && (errno == EINVAL || errno == ENOSYS))
#endif #endif
backend_fd = epoll_create (256); backend_fd = epoll_create (256);
......
...@@ -69,9 +69,6 @@ VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout)) ...@@ -69,9 +69,6 @@ VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout))
VARx(ANFD *, anfds) VARx(ANFD *, anfds)
VARx(int, anfdmax) VARx(int, anfdmax)
#if EV_USE_EVENTFD || EV_GENWRAP
VARx(int, evfd)
#endif
VAR (evpipe, int evpipe [2]) VAR (evpipe, int evpipe [2])
VARx(ev_io, pipe_w) VARx(ev_io, pipe_w)
VARx(EV_ATOMIC_T, pipe_write_wanted) VARx(EV_ATOMIC_T, pipe_write_wanted)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment