]> git.llucax.com Git - software/libev.git/commitdiff
fix and update ev_stat docs
authorroot <root>
Mon, 24 Dec 2007 04:34:00 +0000 (04:34 +0000)
committerroot <root>
Mon, 24 Dec 2007 04:34:00 +0000 (04:34 +0000)
ev.pod

diff --git a/ev.pod b/ev.pod
index 2269dff05bf943283e66142983eb0ff7c7b2ba2a..ac964a9ea855391f5b2ff81fea607a15a4a9d208 100644 (file)
--- a/ev.pod
+++ b/ev.pod
@@ -1498,6 +1498,23 @@ to fall back to regular polling again even with inotify, but changes are
 usually detected immediately, and if the file exists there will be no
 polling.
 
+=head3 The special problem of stat time resolution
+
+The C<stat ()> syscall only supports full-second resolution portably, and
+even on systems where the resolution is higher, many filesystems still
+only support whole seconds.
+
+That means that, if the time is the only thing that changes, you might
+miss updates: on the first update, C<ev_stat> detects a change and calls
+your callback, which does something. When there is another update within
+the same second, C<ev_stat> will be unable to detect it.
+
+The solution to this is to delay acting on a change for a second (or till
+the next second boundary), using a roughly one-second delay C<ev_timer>
+(C<ev_timer_set (w, 0., 1.01); ev_timer_again (loop, w)>). The C<.01>
+is added to work around small timing inconsistencies of some operating
+systems.
+
 =head3 Watcher-Specific Functions and Data Members
 
 =over 4
@@ -1566,8 +1583,36 @@ Example: Watch C</etc/passwd> for attribute changes.
   ...
   ev_stat passwd;
 
-  ev_stat_init (&passwd, passwd_cb, "/etc/passwd");
+  ev_stat_init (&passwd, passwd_cb, "/etc/passwd", 0.);
+  ev_stat_start (loop, &passwd);
+
+Example: Like above, but additionally use a one-second delay so we do not
+miss updates (however, frequent updates will delay processing, too, so
+one might do the work both on C<ev_stat> callback invocation I<and> on
+C<ev_timer> callback invocation).
+
+  static ev_stat passwd;
+  static ev_timer timer;
+
+  static void
+  timer_cb (EV_P_ ev_timer *w, int revents)
+  {
+    ev_timer_stop (EV_A_ w);
+
+    /* now it's one second after the most recent passwd change */
+  }
+
+  static void
+  stat_cb (EV_P_ ev_stat *w, int revents)
+  {
+    /* reset the one-second timer */
+    ev_timer_again (EV_A_ &timer);
+  }
+
+  ...
+  ev_stat_init (&passwd, stat_cb, "/etc/passwd", 0.);
   ev_stat_start (loop, &passwd);
+  ev_timer_init (&timer, timer_cb, 0., 1.01);
 
 
 =head2 C<ev_idle> - when you've got nothing better to do...