--- libev/ev.c 2010/02/16 09:32:39 1.329 +++ libev/ev.c 2010/10/15 22:48:25 1.348 @@ -79,76 +79,85 @@ # endif # endif -# ifndef EV_USE_NANOSLEEP -# if HAVE_NANOSLEEP -# define EV_USE_NANOSLEEP 1 -# else -# define EV_USE_NANOSLEEP 0 +# if HAVE_NANOSLEEP +# ifndef EV_USE_NANOSLEEP +# define EV_USE_NANOSLEEP EV_FEATURE_OS # endif +# else +# undef EV_USE_NANOSLEEP +# define EV_USE_NANOSLEEP 0 # endif -# ifndef EV_USE_SELECT -# if HAVE_SELECT && HAVE_SYS_SELECT_H -# define EV_USE_SELECT 1 -# else -# define EV_USE_SELECT 0 +# if HAVE_SELECT && HAVE_SYS_SELECT_H +# ifndef EV_USE_SELECT +# define EV_USE_SELECT EV_FEATURE_BACKENDS # endif +# else +# undef EV_USE_SELECT +# define EV_USE_SELECT 0 # endif -# ifndef EV_USE_POLL -# if HAVE_POLL && HAVE_POLL_H -# define EV_USE_POLL 1 -# else -# define EV_USE_POLL 0 +# if HAVE_POLL && HAVE_POLL_H +# ifndef EV_USE_POLL +# define EV_USE_POLL EV_FEATURE_BACKENDS # endif +# else +# undef EV_USE_POLL +# define EV_USE_POLL 0 # endif -# ifndef EV_USE_EPOLL -# if HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H -# define EV_USE_EPOLL 1 -# else -# define EV_USE_EPOLL 0 +# if HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H +# ifndef EV_USE_EPOLL +# define EV_USE_EPOLL EV_FEATURE_BACKENDS # endif +# else +# undef EV_USE_EPOLL +# define EV_USE_EPOLL 0 # endif -# ifndef EV_USE_KQUEUE -# if HAVE_KQUEUE && HAVE_SYS_EVENT_H -# define EV_USE_KQUEUE 1 -# else -# define EV_USE_KQUEUE 0 +# if HAVE_KQUEUE && HAVE_SYS_EVENT_H +# ifndef EV_USE_KQUEUE +# define EV_USE_KQUEUE EV_FEATURE_BACKENDS # endif +# else +# undef EV_USE_KQUEUE +# define EV_USE_KQUEUE 0 # endif -# ifndef EV_USE_PORT -# if HAVE_PORT_H && HAVE_PORT_CREATE -# define EV_USE_PORT 1 -# else -# define EV_USE_PORT 0 +# if HAVE_PORT_H && HAVE_PORT_CREATE +# ifndef EV_USE_PORT +# define EV_USE_PORT EV_FEATURE_BACKENDS # endif +# else +# undef EV_USE_PORT +# define EV_USE_PORT 0 # endif -# ifndef EV_USE_INOTIFY -# if HAVE_INOTIFY_INIT && HAVE_SYS_INOTIFY_H -# define EV_USE_INOTIFY 1 -# else -# define EV_USE_INOTIFY 0 +# if HAVE_INOTIFY_INIT && HAVE_SYS_INOTIFY_H +# ifndef EV_USE_INOTIFY +# define EV_USE_INOTIFY EV_FEATURE_OS # endif +# else +# undef EV_USE_INOTIFY +# define EV_USE_INOTIFY 0 # endif -# ifndef EV_USE_SIGNALFD -# if HAVE_SIGNALFD && HAVE_SYS_SIGNALFD_H -# define EV_USE_SIGNALFD 1 -# else -# define EV_USE_SIGNALFD 0 +# if HAVE_SIGNALFD && HAVE_SYS_SIGNALFD_H +# ifndef EV_USE_SIGNALFD +# define EV_USE_SIGNALFD EV_FEATURE_OS # endif +# else +# undef EV_USE_SIGNALFD +# define EV_USE_SIGNALFD 0 # endif -# ifndef EV_USE_EVENTFD -# if HAVE_EVENTFD -# define EV_USE_EVENTFD 1 -# else -# define EV_USE_EVENTFD 0 +# if HAVE_EVENTFD +# ifndef EV_USE_EVENTFD +# define EV_USE_EVENTFD EV_FEATURE_OS # endif +# else +# undef EV_USE_EVENTFD +# define EV_USE_EVENTFD 0 # endif #endif @@ -186,8 +195,17 @@ # ifndef EV_SELECT_IS_WINSOCKET # define EV_SELECT_IS_WINSOCKET 1 # endif +# undef EV_AVOID_STDIO #endif +/* OS X, in its infinite idiocy, actually HARDCODES + * a limit of 1024 into their select. Where people have brains, + * OS X engineers apparently have a vacuum. Or maybe they were + * ordered to have a vacuum, or they do anything for money. + * This might help. Or not. + */ +#define _DARWIN_UNLIMITED_SELECT 1 + /* this block tries to deduce configuration from header-defined symbols and defaults */ /* try to deduce the maximum number of signals on this platform */ @@ -208,18 +226,19 @@ #elif defined (MAX_SIG) # define EV_NSIG (MAX_SIG+1) #elif defined (SIGARRAYSIZE) -# define EV_NSIG SIGARRAYSIZE /* Assume ary[SIGARRAYSIZE] */ +# define EV_NSIG (SIGARRAYSIZE) /* Assume ary[SIGARRAYSIZE] */ #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 */ +/* to make it compile regardless, just remove the above line, */ +/* but consider reporting it, too! :) */ # define EV_NSIG 65 #endif #ifndef EV_USE_CLOCK_SYSCALL # if __linux && __GLIBC__ >= 2 -# define EV_USE_CLOCK_SYSCALL 1 +# define EV_USE_CLOCK_SYSCALL EV_FEATURE_OS # else # define EV_USE_CLOCK_SYSCALL 0 # endif @@ -227,7 +246,7 @@ #ifndef EV_USE_MONOTONIC # if defined (_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 -# define EV_USE_MONOTONIC 1 +# define EV_USE_MONOTONIC EV_FEATURE_OS # else # define EV_USE_MONOTONIC 0 # endif @@ -239,27 +258,27 @@ #ifndef EV_USE_NANOSLEEP # if _POSIX_C_SOURCE >= 199309L -# define EV_USE_NANOSLEEP 1 +# define EV_USE_NANOSLEEP EV_FEATURE_OS # else # define EV_USE_NANOSLEEP 0 # endif #endif #ifndef EV_USE_SELECT -# define EV_USE_SELECT 1 +# define EV_USE_SELECT EV_FEATURE_BACKENDS #endif #ifndef EV_USE_POLL # ifdef _WIN32 # define EV_USE_POLL 0 # else -# define EV_USE_POLL 1 +# define EV_USE_POLL EV_FEATURE_BACKENDS # endif #endif #ifndef EV_USE_EPOLL # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4)) -# define EV_USE_EPOLL 1 +# define EV_USE_EPOLL EV_FEATURE_BACKENDS # else # define EV_USE_EPOLL 0 # endif @@ -275,31 +294,23 @@ #ifndef EV_USE_INOTIFY # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4)) -# define EV_USE_INOTIFY 1 +# define EV_USE_INOTIFY EV_FEATURE_OS # else # define EV_USE_INOTIFY 0 # endif #endif #ifndef EV_PID_HASHSIZE -# if EV_MINIMAL -# define EV_PID_HASHSIZE 1 -# else -# define EV_PID_HASHSIZE 16 -# endif +# define EV_PID_HASHSIZE EV_FEATURE_DATA ? 16 : 1 #endif #ifndef EV_INOTIFY_HASHSIZE -# if EV_MINIMAL -# define EV_INOTIFY_HASHSIZE 1 -# else -# define EV_INOTIFY_HASHSIZE 16 -# endif +# define EV_INOTIFY_HASHSIZE EV_FEATURE_DATA ? 16 : 1 #endif #ifndef EV_USE_EVENTFD # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) -# define EV_USE_EVENTFD 1 +# define EV_USE_EVENTFD EV_FEATURE_OS # else # define EV_USE_EVENTFD 0 # endif @@ -307,7 +318,7 @@ #ifndef EV_USE_SIGNALFD # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) -# define EV_USE_SIGNALFD 1 +# define EV_USE_SIGNALFD EV_FEATURE_OS # else # define EV_USE_SIGNALFD 0 # endif @@ -320,15 +331,15 @@ #endif #ifndef EV_VERIFY -# define EV_VERIFY !EV_MINIMAL +# define EV_VERIFY (EV_FEATURE_API ? 1 : 0) #endif #ifndef EV_USE_4HEAP -# define EV_USE_4HEAP !EV_MINIMAL +# define EV_USE_4HEAP EV_FEATURE_DATA #endif #ifndef EV_HEAP_CACHE_AT -# define EV_HEAP_CACHE_AT !EV_MINIMAL +# define EV_HEAP_CACHE_AT EV_FEATURE_DATA #endif /* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */ @@ -439,11 +450,10 @@ # endif #endif - /**/ #if EV_VERIFY >= 3 -# define EV_FREQUENT_CHECK ev_loop_verify (EV_A) +# define EV_FREQUENT_CHECK ev_verify (EV_A) #else # define EV_FREQUENT_CHECK do { } while (0) #endif @@ -461,6 +471,9 @@ #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ #define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */ +#define EV_TV_SET(tv,t) do { tv.tv_sec = (long)t; tv.tv_usec = (long)((t - tv.tv_sec) * 1e6); } while (0) +#define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0) + #if __GNUC__ >= 4 # define expect(expr,value) __builtin_expect ((expr),(value)) # define noinline __attribute__ ((noinline)) @@ -476,10 +489,10 @@ #define expect_true(expr) expect ((expr) != 0, 1) #define inline_size static inline -#if EV_MINIMAL -# define inline_speed static noinline -#else +#if EV_FEATURE_CODE # define inline_speed static inline +#else +# define inline_speed static noinline #endif #define NUMPRI (EV_MAXPRI - EV_MINPRI + 1) @@ -502,7 +515,7 @@ #if EV_USE_REALTIME /* sig_atomic_t is used to avoid per-thread variables or locking but still */ -/* giving it a reasonably high chance of working on typical architetcures */ +/* giving it a reasonably high chance of working on typical architectures */ static EV_ATOMIC_T have_realtime; /* did clock_gettime (CLOCK_REALTIME) work? */ #endif @@ -526,6 +539,14 @@ /*****************************************************************************/ +#if EV_AVOID_STDIO +static void noinline +ev_printerr (const char *msg) +{ + write (STDERR_FILENO, msg, strlen (msg)); +} +#endif + static void (*syserr_cb)(const char *msg); void @@ -544,7 +565,16 @@ syserr_cb (msg); else { +#if EV_AVOID_STDIO + const char *err = strerror (errno); + + ev_printerr (msg); + ev_printerr (": "); + ev_printerr (err); + ev_printerr ("\n"); +#else perror (msg); +#endif abort (); } } @@ -552,8 +582,11 @@ static void * ev_realloc_emul (void *ptr, long size) { +#if __GLIBC__ + return realloc (ptr, size); +#else /* some systems, notably openbsd and darwin, fail to properly - * implement realloc (x, 0) (as required by both ansi c-98 and + * implement realloc (x, 0) (as required by both ansi c-89 and * the single unix specification, so work around them here. */ @@ -562,6 +595,7 @@ free (ptr); return 0; +#endif } static void *(*alloc)(void *ptr, long size) = ev_realloc_emul; @@ -579,7 +613,11 @@ if (!ptr && size) { +#if EV_AVOID_STDIO + ev_printerr ("libev: memory allocation failed, aborting.\n"); +#else fprintf (stderr, "libev: cannot allocate %ld bytes, aborting.", size); +#endif abort (); } @@ -671,7 +709,7 @@ #endif -#if EV_MINIMAL < 2 +#if EV_FEATURE_API # define EV_RELEASE_CB if (expect_false (release_cb)) release_cb (EV_A) # define EV_ACQUIRE_CB if (expect_false (acquire_cb)) acquire_cb (EV_A) # define EV_INVOKE_PENDING invoke_cb (EV_A) @@ -735,21 +773,17 @@ #if EV_USE_NANOSLEEP struct timespec ts; - ts.tv_sec = (time_t)delay; - ts.tv_nsec = (long)((delay - (ev_tstamp)(ts.tv_sec)) * 1e9); - + EV_TS_SET (ts, delay); nanosleep (&ts, 0); #elif defined(_WIN32) Sleep ((unsigned long)(delay * 1e3)); #else struct timeval tv; - tv.tv_sec = (time_t)delay; - tv.tv_usec = (long)((delay - (ev_tstamp)(tv.tv_sec)) * 1e6); - /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */ /* something not guaranteed by newer posix versions, but guaranteed */ /* by older ones */ + EV_TS_SET (tv, delay); select (0, 0, 0, 0, &tv); #endif } @@ -760,7 +794,7 @@ #define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */ /* find a suitable new size for the given array, */ -/* hopefully by rounding to a ncie-to-malloc size */ +/* hopefully by rounding to a nice-to-malloc size */ inline_size int array_nextsize (int elem, int cur, int cnt) { @@ -866,7 +900,7 @@ /*****************************************************************************/ inline_speed void -fd_event_nc (EV_P_ int fd, int revents) +fd_event_nocheck (EV_P_ int fd, int revents) { ANFD *anfd = anfds + fd; ev_io *w; @@ -888,14 +922,14 @@ ANFD *anfd = anfds + fd; if (expect_true (!anfd->reify)) - fd_event_nc (EV_A_ fd, revents); + fd_event_nocheck (EV_A_ fd, revents); } void ev_feed_fd_event (EV_P_ int fd, int revents) { if (fd >= 0 && fd < anfdmax) - fd_event_nc (EV_A_ fd, revents); + fd_event_nocheck (EV_A_ fd, revents); } /* make sure the external fd watch events are in-sync */ @@ -968,7 +1002,7 @@ } } -/* check whether the given fd is atcually valid, for error recovery */ +/* check whether the given fd is actually valid, for error recovery */ inline_size int fd_valid (int fd) { @@ -1020,10 +1054,24 @@ } } +/* used to prepare libev internal fd's */ +/* this is not fork-safe */ +inline_speed void +fd_intern (int fd) +{ +#ifdef _WIN32 + unsigned long arg = 1; + ioctlsocket (EV_FD_TO_WIN32_HANDLE (fd), FIONBIO, &arg); +#else + fcntl (fd, F_SETFD, FD_CLOEXEC); + fcntl (fd, F_SETFL, O_NONBLOCK); +#endif +} + /*****************************************************************************/ /* - * the heap functions want a real array index. array index 0 uis guaranteed to not + * the heap functions want a real array index. array index 0 is guaranteed to not * be in-use at any time. the first heap entry is at array [HEAP0]. DHEAP gives * the branching factor of the d-tree. */ @@ -1181,26 +1229,14 @@ /*****************************************************************************/ -/* used to prepare libev internal fd's */ -/* this is not fork-safe */ -inline_speed void -fd_intern (int fd) -{ -#ifdef _WIN32 - unsigned long arg = 1; - ioctlsocket (EV_FD_TO_WIN32_HANDLE (fd), FIONBIO, &arg); -#else - fcntl (fd, F_SETFD, FD_CLOEXEC); - fcntl (fd, F_SETFL, O_NONBLOCK); -#endif -} +#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE static void noinline evpipe_init (EV_P) { if (!ev_is_active (&pipe_w)) { -#if EV_USE_EVENTFD +# if EV_USE_EVENTFD evfd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC); if (evfd < 0 && errno == EINVAL) evfd = eventfd (0, 0); @@ -1212,7 +1248,7 @@ ev_io_set (&pipe_w, evfd, EV_READ); } else -#endif +# endif { while (pipe (evpipe)) ev_syserr ("(libev) error creating signal/async pipe"); @@ -1233,6 +1269,7 @@ if (!*flag) { int old_errno = errno; /* save errno because write might clobber it */ + char dummy; *flag = 1; @@ -1244,7 +1281,12 @@ } else #endif - write (evpipe [1], &old_errno, 1); + /* win32 people keep sending patches that change this write() to send() */ + /* and then run away. but send() is wrong, it wants a socket handle on win32 */ + /* so when you think this write should be a send instead, please find out */ + /* where your send() is from - it's definitely not the microsoft send, and */ + /* tell me. thank you. */ + write (evpipe [1], &dummy, 1); errno = old_errno; } @@ -1267,6 +1309,7 @@ #endif { char dummy; + /* see discussion in evpipe_write when you think this read should be recv in win32 */ read (evpipe [0], &dummy, 1); } @@ -1355,12 +1398,13 @@ } #endif +#endif + /*****************************************************************************/ +#if EV_CHILD_ENABLE static WL childs [EV_PID_HASHSIZE]; -#ifndef _WIN32 - static ev_signal childev; #ifndef WIFCONTINUED @@ -1374,7 +1418,7 @@ ev_child *w; int traced = WIFSTOPPED (status) || WIFCONTINUED (status); - for (w = (ev_child *)childs [chain & (EV_PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next) + for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next) { if ((w->pid == pid || !w->pid) && (!traced || (w->flags & 1))) @@ -1409,7 +1453,7 @@ ev_feed_event (EV_A_ (W)sw, EV_SIGNAL); child_reap (EV_A_ pid, pid, status); - if (EV_PID_HASHSIZE > 1) + if ((EV_PID_HASHSIZE) > 1) child_reap (EV_A_ 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */ } @@ -1486,6 +1530,9 @@ flags &= ~EVBACKEND_KQUEUE; /* horribly broken, even for sockets */ flags &= ~EVBACKEND_POLL; /* poll is based on kqueue from 10.5 onwards */ #endif +#ifdef __FreeBSD__ + flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */ +#endif return flags; } @@ -1508,15 +1555,15 @@ return backend; } -#if EV_MINIMAL < 2 +#if EV_FEATURE_API unsigned int -ev_loop_count (EV_P) +ev_iteration (EV_P) { return loop_count; } unsigned int -ev_loop_depth (EV_P) +ev_depth (EV_P) { return loop_depth; } @@ -1598,7 +1645,7 @@ mn_now = get_clock (); now_floor = mn_now; rtmn_diff = ev_rt_now - mn_now; -#if EV_MINIMAL < 2 +#if EV_FEATURE_API invoke_cb = ev_invoke_pending; #endif @@ -1638,8 +1685,10 @@ ev_prepare_init (&pending_w, pendingcb); +#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE ev_init (&pipe_w, pipecb); ev_set_priority (&pipe_w, EV_MAXPRI); +#endif } } @@ -1767,9 +1816,11 @@ EV_WIN32_CLOSE_FD (evpipe [1]); } +#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE evpipe_init (EV_A); /* now iterate over everything, in case we missed something */ pipecb (EV_A_ &pipe_w, EV_READ); +#endif } postfork = 0; @@ -1841,9 +1892,9 @@ } #endif -#if EV_MINIMAL < 2 +#if EV_FEATURE_API void -ev_loop_verify (EV_P) +ev_verify (EV_P) { #if EV_VERIFY int i; @@ -1892,15 +1943,21 @@ array_verify (EV_A_ (W *)asyncs, asynccnt); #endif +#if EV_PREPARE_ENABLE assert (preparemax >= preparecnt); array_verify (EV_A_ (W *)prepares, preparecnt); +#endif +#if EV_CHECK_ENABLE assert (checkmax >= checkcnt); array_verify (EV_A_ (W *)checks, checkcnt); +#endif # if 0 - for (w = (ev_child *)childs [chain & (EV_PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next) +#if EV_CHILD_ENABLE + for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next) for (signum = EV_NSIG; signum--; ) if (signals [signum].pending) +#endif # endif #endif } @@ -1926,7 +1983,7 @@ if (ev_backend (EV_A)) { -#ifndef _WIN32 +#if EV_CHILD_ENABLE ev_signal_init (&childev, childcb, SIGCHLD); ev_set_priority (&childev, EV_MAXPRI); ev_signal_start (EV_A_ &childev); @@ -1949,7 +2006,7 @@ ev_default_loop_ptr = 0; -#ifndef _WIN32 +#if EV_CHILD_ENABLE ev_ref (EV_A); /* child watcher */ ev_signal_stop (EV_A_ &childev); #endif @@ -2065,7 +2122,7 @@ } while (timercnt && ANHE_at (timers [HEAP0]) < mn_now); - feed_reverse_done (EV_A_ EV_TIMEOUT); + feed_reverse_done (EV_A_ EV_TIMER); } } @@ -2128,7 +2185,7 @@ } /* simply recalculate all periodics */ -/* TODO: maybe ensure that at leats one event happens when jumping forward? */ +/* TODO: maybe ensure that at least one event happens when jumping forward? */ static void noinline periodics_reschedule (EV_P) { @@ -2236,7 +2293,7 @@ void ev_loop (EV_P_ int flags) { -#if EV_MINIMAL < 2 +#if EV_FEATURE_API ++loop_depth; #endif @@ -2249,7 +2306,7 @@ do { #if EV_VERIFY >= 2 - ev_loop_verify (EV_A); + ev_verify (EV_A); #endif #ifndef _WIN32 @@ -2271,12 +2328,14 @@ } #endif +#if EV_PREPARE_ENABLE /* queue prepare watchers (and execute them) */ if (expect_false (preparecnt)) { queue_events (EV_A_ (W *)prepares, preparecnt, EV_PREPARE); EV_INVOKE_PENDING; } +#endif if (expect_false (loop_done)) break; @@ -2337,7 +2396,7 @@ } } -#if EV_MINIMAL < 2 +#if EV_FEATURE_API ++loop_count; #endif assert ((loop_done = EVUNLOOP_RECURSE, 1)); /* assert for side effect */ @@ -2359,9 +2418,11 @@ idle_reify (EV_A); #endif +#if EV_CHECK_ENABLE /* queue check watchers, to be executed first */ if (expect_false (checkcnt)) queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK); +#endif EV_INVOKE_PENDING; } @@ -2374,7 +2435,7 @@ if (loop_done == EVUNLOOP_ONE) loop_done = EVUNLOOP_CANCEL; -#if EV_MINIMAL < 2 +#if EV_FEATURE_API --loop_depth; #endif } @@ -2701,6 +2762,8 @@ # define SA_RESTART 0 #endif +#if EV_SIGNAL_ENABLE + void noinline ev_signal_start (EV_P_ ev_signal *w) { @@ -2816,6 +2879,10 @@ EV_FREQUENT_CHECK; } +#endif + +#if EV_CHILD_ENABLE + void ev_child_start (EV_P_ ev_child *w) { @@ -2828,7 +2895,7 @@ EV_FREQUENT_CHECK; ev_start (EV_A_ (W)w, 1); - wlist_add (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w); + wlist_add (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w); EV_FREQUENT_CHECK; } @@ -2842,12 +2909,14 @@ EV_FREQUENT_CHECK; - wlist_del (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w); + wlist_del (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w); ev_stop (EV_A_ (W)w); EV_FREQUENT_CHECK; } +#endif + #if EV_STAT_ENABLE # ifdef _WIN32 @@ -2923,7 +2992,7 @@ } if (w->wd >= 0) - wlist_add (&fs_hash [w->wd & (EV_INOTIFY_HASHSIZE - 1)].head, (WL)w); + wlist_add (&fs_hash [w->wd & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w); /* now re-arm timer, if required */ if (ev_is_active (&w->timer)) ev_ref (EV_A); @@ -2941,7 +3010,7 @@ return; w->wd = -2; - slot = wd & (EV_INOTIFY_HASHSIZE - 1); + slot = wd & ((EV_INOTIFY_HASHSIZE) - 1); wlist_del (&fs_hash [slot].head, (WL)w); /* remove this watcher, if others are watching it, they will rearm */ @@ -2953,13 +3022,13 @@ { if (slot < 0) /* overflow, need to check for all hash slots */ - for (slot = 0; slot < EV_INOTIFY_HASHSIZE; ++slot) + for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot) infy_wd (EV_A_ slot, wd, ev); else { WL w_; - for (w_ = fs_hash [slot & (EV_INOTIFY_HASHSIZE - 1)].head; w_; ) + for (w_ = fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head; w_; ) { ev_stat *w = (ev_stat *)w_; w_ = w_->next; /* lets us remove this watcher and all before it */ @@ -2968,7 +3037,7 @@ { if (ev->mask & (IN_IGNORED | IN_UNMOUNT | IN_DELETE_SELF)) { - wlist_del (&fs_hash [slot & (EV_INOTIFY_HASHSIZE - 1)].head, (WL)w); + wlist_del (&fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w); w->wd = -1; infy_add (EV_A_ w); /* re-add, no matter what */ } @@ -2994,24 +3063,45 @@ } } -inline_size void -check_2625 (EV_P) +inline_size unsigned int +ev_linux_version (void) { - /* kernels < 2.6.25 are borked - * http://www.ussg.indiana.edu/hypermail/linux/kernel/0711.3/1208.html - */ struct utsname buf; - int major, minor, micro; + unsigned int v; + int i; + char *p = buf.release; if (uname (&buf)) - return; + return 0; - if (sscanf (buf.release, "%d.%d.%d", &major, &minor, µ) != 3) - return; + for (i = 3+1; --i; ) + { + unsigned int c = 0; + + for (;;) + { + if (*p >= '0' && *p <= '9') + c = c * 10 + *p++ - '0'; + else + { + p += *p == '.'; + break; + } + } + + v = (v << 8) | c; + } + + return v; +} - if (major < 2 - || (major == 2 && minor < 6) - || (major == 2 && minor == 6 && micro < 25)) +inline_size void +ev_check_2625 (EV_P) +{ + /* kernels < 2.6.25 are borked + * http://www.ussg.indiana.edu/hypermail/linux/kernel/0711.3/1208.html + */ + if (ev_linux_version () < 0x020619) return; fs_2625 = 1; @@ -3036,7 +3126,7 @@ fs_fd = -1; - check_2625 (EV_A); + ev_check_2625 (EV_A); fs_fd = infy_newfd (); @@ -3071,7 +3161,7 @@ ev_unref (EV_A); } - for (slot = 0; slot < EV_INOTIFY_HASHSIZE; ++slot) + for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot) { WL w_ = fs_hash [slot].head; fs_hash [slot].head = 0; @@ -3256,6 +3346,7 @@ } #endif +#if EV_PREPARE_ENABLE void ev_prepare_start (EV_P_ ev_prepare *w) { @@ -3291,7 +3382,9 @@ EV_FREQUENT_CHECK; } +#endif +#if EV_CHECK_ENABLE void ev_check_start (EV_P_ ev_check *w) { @@ -3327,6 +3420,7 @@ EV_FREQUENT_CHECK; } +#endif #if EV_EMBED_ENABLE void noinline @@ -3568,7 +3662,7 @@ if (expect_false (!once)) { - cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMEOUT, arg); + cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMER, arg); return; } @@ -3665,17 +3759,22 @@ cb (EV_A_ EV_ASYNC, asyncs [i]); #endif +#if EV_PREPARE_ENABLE if (types & EV_PREPARE) for (i = preparecnt; i--; ) -#if EV_EMBED_ENABLE +# if EV_EMBED_ENABLE if (ev_cb (prepares [i]) != embed_prepare_cb) -#endif +# endif cb (EV_A_ EV_PREPARE, prepares [i]); +#endif +#if EV_CHECK_ENABLE if (types & EV_CHECK) for (i = checkcnt; i--; ) cb (EV_A_ EV_CHECK, checks [i]); +#endif +#if EV_SIGNAL_ENABLE if (types & EV_SIGNAL) for (i = 0; i < EV_NSIG - 1; ++i) for (wl = signals [i].head; wl; ) @@ -3684,15 +3783,18 @@ cb (EV_A_ EV_SIGNAL, wl); wl = wn; } +#endif +#if EV_CHILD_ENABLE if (types & EV_CHILD) - for (i = EV_PID_HASHSIZE; i--; ) + for (i = (EV_PID_HASHSIZE); i--; ) for (wl = childs [i]; wl; ) { wn = wl->next; cb (EV_A_ EV_CHILD, wl); wl = wn; } +#endif /* EV_STAT 0x00001000 /* stat data changed */ /* EV_EMBED 0x00010000 /* embedded event loop needs sweep */ }