From 88681d910ed1d5eaea3c75b6ffb560e77c39428b Mon Sep 17 00:00:00 2001
From: root <root>
Date: Mon, 13 Oct 2008 23:20:12 +0000
Subject: *** empty log message ***

---
 Changes |  5 +++++
 ev.c    | 34 +++++++++++++++++++++++++++++-----
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/Changes b/Changes
index 346d5fc..16d61d1 100644
--- a/Changes
+++ b/Changes
@@ -2,6 +2,11 @@ Revision history for libev, a high-performance and full-featured event loop.
 
 
 WISH? monotonic clocks times/GetTickCount for coarse corrections?
+	- disable inotify usage on linux <2.6.25, as it is broken
+          (reported by Yoann Vandoorselaere).
+        - ev_stat errornously would try to add inotify watchers
+          even when inotify isn't available (this should only
+          have a performance impact).
 	- ev_once now passes both timeout and io to the callback if both
           occur concurrently, instead of giving timeouts precedence.
 	- disable EV_USE_INOTIFY when sys/inotify.h is too old.
diff --git a/ev.c b/ev.c
index 617f5ad..1d041fe 100644
--- a/ev.c
+++ b/ev.c
@@ -288,6 +288,7 @@ extern "C" {
 #endif
 
 #if EV_USE_INOTIFY
+# include <sys/utsname.h>
 # include <sys/inotify.h>
 /* some very old inotify.h headers don't have IN_DONT_FOLLOW */
 # ifndef IN_DONT_FOLLOW
@@ -2498,7 +2499,7 @@ static void noinline
 infy_wd (EV_P_ int slot, int wd, struct inotify_event *ev)
 {
   if (slot < 0)
-    /* overflow, need to check for all hahs slots */
+    /* overflow, need to check for all hash slots */
     for (slot = 0; slot < EV_INOTIFY_HASHSIZE; ++slot)
       infy_wd (EV_A_ slot, wd, ev);
   else
@@ -2542,6 +2543,27 @@ infy_init (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;
+
+    fs_fd = -1;
+
+    if (uname (&buf))
+      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;
+  }
+
   fs_fd = inotify_init ();
 
   if (fs_fd >= 0)
@@ -2580,7 +2602,6 @@ infy_fork (EV_P)
           else
             ev_timer_start (EV_A_ &w->timer);
         }
-
     }
 }
 
@@ -2626,9 +2647,12 @@ stat_timer_cb (EV_P_ ev_timer *w_, int revents)
     || w->prev.st_ctime != w->attr.st_ctime
   ) {
       #if EV_USE_INOTIFY
-        infy_del (EV_A_ w);
-        infy_add (EV_A_ w);
-        ev_stat_stat (EV_A_ w); /* avoid race... */
+        if (fs_fd >= 0)
+          {
+            infy_del (EV_A_ w);
+            infy_add (EV_A_ w);
+            ev_stat_stat (EV_A_ w); /* avoid race... */
+          }
       #endif
 
       ev_feed_event (EV_A_ w, EV_STAT);
-- 
cgit v1.2.3