diff options
| -rw-r--r-- | Changes | 4 | ||||
| -rw-r--r-- | ev.c | 71 | 
2 files changed, 47 insertions, 28 deletions
| @@ -3,8 +3,8 @@ Revision history for libev, a high-performance and full-featured event loop.  TODO: somehow unblock procmask?  	- backport inotify code to C89.          - inotify file descriptors could leak into child processes. -        - inotify usage would keep an errornous extra ref on the loop, -          preventing exit when unregistering all watchers (testcase +        - ev_stat watchers could keep an errornous extra ref on the loop, +          preventing exit when unregistering all watchers (testcases            provided by ry@tinyclouds.org).          - implement EV_WIN32_HANDLE_TO_FD and EV_WIN32_CLOSE_FD configuration            symbols to make it easier for apps to do their own fd management. @@ -2858,12 +2858,33 @@ infy_add (EV_P_ ev_stat *w)  {    w->wd = inotify_add_watch (fs_fd, w->path, IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY | IN_DONT_FOLLOW | IN_MASK_ADD); -  if (w->wd < 0) +  if (w->wd >= 0) +    { +      struct statfs sfs; + +      /* now local changes will be tracked by inotify, but remote changes won't */ +      /* unless the filesystem is known to be local, we therefore still poll */ +      /* also do poll on <2.6.25, but with normal frequency */ + +      if (!fs_2625) +        w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL; +      else if (!statfs (w->path, &sfs) +               && (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 */)) +        w->timer.repeat = 0.; /* filesystem is local, kernel new enough */ +      else +        w->timer.repeat = w->interval ? w->interval : NFS_STAT_INTERVAL; /* remote, use reduced frequency */ +    } +  else      { +      /* can't use inotify, continue to stat */        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 */ +      /* if path is not there, monitor some parent directory for speedup hints */        /* note that exceeding the hardcoded path limit is not a correctness issue, */        /* but an efficiency issue only */        if ((errno == ENOENT || errno == EACCES) && strlen (w->path) < 4096) @@ -2889,27 +2910,12 @@ infy_add (EV_P_ ev_stat *w)      }    if (w->wd >= 0) -    { -      struct statfs sfs; - -      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 is known to be local, we therefore still poll */ -      /* also do poll on <2.6.25, but with normal frequency */ - -      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; +    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); -    } +  /* now re-arm timer, if required */ +  if (ev_is_active (&w->timer)) ev_ref (EV_A); +  ev_timer_again (EV_A_ &w->timer); +  if (ev_is_active (&w->timer)) ev_unref (EV_A);  }  static void noinline @@ -3064,7 +3070,12 @@ infy_fork (EV_P)            if (fs_fd >= 0)              infy_add (EV_A_ w); /* re-add, no matter what */            else -            ev_timer_again (EV_A_ &w->timer); +            { +              w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL; +              if (ev_is_active (&w->timer)) ev_ref (EV_A); +              ev_timer_again (EV_A_ &w->timer); +              if (ev_is_active (&w->timer)) ev_unref (EV_A); +            }          }      }  } @@ -3144,7 +3155,10 @@ ev_stat_start (EV_P_ ev_stat *w)      infy_add (EV_A_ w);    else  #endif -    ev_timer_again (EV_A_ &w->timer); +    { +      ev_timer_again (EV_A_ &w->timer); +      ev_unref (EV_A); +    }    ev_start (EV_A_ (W)w, 1); @@ -3163,7 +3177,12 @@ ev_stat_stop (EV_P_ ev_stat *w)  #if EV_USE_INOTIFY    infy_del (EV_A_ w);  #endif -  ev_timer_stop (EV_A_ &w->timer); + +  if (ev_is_active (&w->timer)) +    { +      ev_ref (EV_A); +      ev_timer_stop (EV_A_ &w->timer); +    }    ev_stop (EV_A_ (W)w); | 
