From af8cc2d33fae64c76948b12db9814533b2562aac Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 Nov 2008 14:27:06 +0000 Subject: *** empty log message *** --- Changes | 5 +++- ev++.h | 1 + ev.c | 85 +++++++++++++++++++++++++++++++++++++++------------------------ ev_vars.h | 1 + ev_wrap.h | 2 ++ 5 files changed, 61 insertions(+), 33 deletions(-) diff --git a/Changes b/Changes index 3e01b7c..0a388df 100644 --- a/Changes +++ b/Changes @@ -2,7 +2,10 @@ Revision history for libev, a high-performance and full-featured event loop. WISH? monotonic clocks times/GetTickCount for coarse corrections? -TODO: "ev_stat on nfs" + - ev_stat watchers will now use inotify as a mere hint on + kernels <2.6.25, or if the filesystem is not in the + "known to be good" list. + 3.48 Thu Oct 30 09:02:37 CET 2008 - further optimise away the EPOLL_CTL_ADD/MOD combo in the epoll backend by assuming the kernel event mask hasn't changed if diff --git a/ev++.h b/ev++.h index c400bf1..a17efa2 100644 --- a/ev++.h +++ b/ev++.h @@ -74,6 +74,7 @@ namespace ev { FORK = EV_FORK, ASYNC = EV_ASYNC, EMBED = EV_EMBED, +# undef ERROR // some systems stupidly #define ERROR ERROR = EV_ERROR, }; diff --git a/ev.c b/ev.c index 464ce41..c872176 100644 --- a/ev.c +++ b/ev.c @@ -289,6 +289,7 @@ extern "C" { #if EV_USE_INOTIFY # include +# include # include /* some very old inotify.h headers don't have IN_DONT_FOLLOW */ # ifndef IN_DONT_FOLLOW @@ -2416,8 +2417,9 @@ ev_child_stop (EV_P_ ev_child *w) # define lstat(a,b) _stati64 (a,b) # endif -#define DEF_STAT_INTERVAL 5.0074891 -#define MIN_STAT_INTERVAL 0.1074891 +#define DEF_STAT_INTERVAL 5.0074891 +#define NFS_STAT_INTERVAL 30.1074891 /* for filesystems potentially failing inotify */ +#define MIN_STAT_INTERVAL 0.1074891 static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents); @@ -2431,7 +2433,8 @@ infy_add (EV_P_ ev_stat *w) if (w->wd < 0) { - ev_timer_start (EV_A_ &w->timer); /* this is not race-free, so we still need to recheck periodically */ + w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL; + ev_timer_again (EV_A_ &w->timer); /* this is not race-free, so we still need to recheck periodically */ /* monitor some parent directory for speedup hints */ /* note that exceeding the hardcoded path limit is not a correctness issue, */ @@ -2458,10 +2461,26 @@ infy_add (EV_P_ ev_stat *w) } } else - ev_timer_stop (EV_A_ &w->timer); /* we can watch this in a race-free way */ + { + wlist_add (&fs_hash [w->wd & (EV_INOTIFY_HASHSIZE - 1)].head, (WL)w); + + /* now local changes will be tracked by inotify, but remote changes won't */ + /* unless the filesystem it known to be local, we therefore still poll */ + /* also do poll on <2.6.25, but with normal frequency */ + struct statfs sfs; + + if (fs_2625 && !statfs (w->path, &sfs)) + if (sfs.f_type == 0x1373 /* devfs */ + || sfs.f_type == 0xEF53 /* ext2/3 */ + || sfs.f_type == 0x3153464a /* jfs */ + || sfs.f_type == 0x52654973 /* reiser3 */ + || sfs.f_type == 0x01021994 /* tempfs */ + || sfs.f_type == 0x58465342 /* xfs */) + return; - if (w->wd >= 0) - wlist_add (&fs_hash [w->wd & (EV_INOTIFY_HASHSIZE - 1)].head, (WL)w); + w->timer.repeat = w->interval ? w->interval : fs_2625 ? NFS_STAT_INTERVAL : DEF_STAT_INTERVAL; + ev_timer_again (EV_A_ &w->timer); + } } static void noinline @@ -2524,31 +2543,37 @@ infy_cb (EV_P_ ev_io *w, int revents) } void inline_size -infy_init (EV_P) +check_2625 (EV_P) { - if (fs_fd != -2) - return; - /* 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; + struct utsname buf; + int major, minor, micro; - fs_fd = -1; + if (uname (&buf)) + return; - if (uname (&buf)) - return; + if (sscanf (buf.release, "%d.%d.%d", &major, &minor, µ) != 3) + return; - if (sscanf (buf.release, "%d.%d.%d", &major, &minor, µ) != 3) - return; + if (major < 2 + || (major == 2 && minor < 6) + || (major == 2 && minor == 6 && micro < 25)) + return; - if (major < 2 - || (major == 2 && minor < 6) - || (major == 2 && minor == 6 && micro < 25)) - return; - } + fs_2625 = 1; +} + +void inline_size +infy_init (EV_P) +{ + if (fs_fd != -2) + return; + + fs_fd = -1; + + check_2625 (EV_A); fs_fd = inotify_init (); @@ -2586,7 +2611,7 @@ infy_fork (EV_P) if (fs_fd >= 0) infy_add (EV_A_ w); /* re-add, no matter what */ else - ev_timer_start (EV_A_ &w->timer); + ev_timer_again (EV_A_ &w->timer); } } } @@ -2651,16 +2676,12 @@ ev_stat_start (EV_P_ ev_stat *w) if (expect_false (ev_is_active (w))) return; - /* since we use memcmp, we need to clear any padding data etc. */ - memset (&w->prev, 0, sizeof (ev_statdata)); - memset (&w->attr, 0, sizeof (ev_statdata)); - ev_stat_stat (EV_A_ w); - if (w->interval < MIN_STAT_INTERVAL) - w->interval = w->interval ? MIN_STAT_INTERVAL : DEF_STAT_INTERVAL; + if (w->interval < MIN_STAT_INTERVAL && w->interval) + w->interval = MIN_STAT_INTERVAL; - ev_timer_init (&w->timer, stat_timer_cb, w->interval, w->interval); + ev_timer_init (&w->timer, stat_timer_cb, 0., w->interval ? w->interval : DEF_STAT_INTERVAL); ev_set_priority (&w->timer, ev_priority (w)); #if EV_USE_INOTIFY @@ -2670,7 +2691,7 @@ ev_stat_start (EV_P_ ev_stat *w) infy_add (EV_A_ w); else #endif - ev_timer_start (EV_A_ &w->timer); + ev_timer_again (EV_A_ &w->timer); ev_start (EV_A_ (W)w, 1); diff --git a/ev_vars.h b/ev_vars.h index ac0ec61..3290a57 100644 --- a/ev_vars.h +++ b/ev_vars.h @@ -156,6 +156,7 @@ VARx(int, asynccnt) #if EV_USE_INOTIFY || EV_GENWRAP VARx(int, fs_fd) VARx(ev_io, fs_w) +VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */ VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE]) #endif diff --git a/ev_wrap.h b/ev_wrap.h index 6ccc1d2..ad545bf 100644 --- a/ev_wrap.h +++ b/ev_wrap.h @@ -71,6 +71,7 @@ #define asynccnt ((loop)->asynccnt) #define fs_fd ((loop)->fs_fd) #define fs_w ((loop)->fs_w) +#define fs_2625 ((loop)->fs_2625) #define fs_hash ((loop)->fs_hash) #else #undef EV_WRAP_H @@ -144,5 +145,6 @@ #undef asynccnt #undef fs_fd #undef fs_w +#undef fs_2625 #undef fs_hash #endif -- cgit v1.2.3