Browse Source

*** empty log message ***

master
Marc Alexander Lehmann 13 years ago
parent
commit
b6aad328f7
  1. 5
      Changes
  2. 1
      ev++.h
  3. 85
      ev.c
  4. 1
      ev_vars.h
  5. 2
      ev_wrap.h

5
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

1
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,
};

85
ev.c

@ -289,6 +289,7 @@ extern "C" {
#if EV_USE_INOTIFY
# include <sys/utsname.h>
# include <sys/statfs.h>
# include <sys/inotify.h>
/* 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, &micro) != 3)
return;
if (sscanf (buf.release, "%d.%d.%d", &major, &minor, &micro) != 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);

1
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

2
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
Loading…
Cancel
Save