ev_stat inotify implementation might miss events

Marc Lehmann schmorp at schmorp.de
Mon Jan 25 21:44:36 CET 2010


On Mon, Jan 25, 2010 at 08:46:37PM +0100, Yoann Vandoorselaere <yoann.v at prelude-ids.com> wrote:
> Every write will trigger a libev events *if* the libev specified
> callback function return sufficiently fast. 

Yes, and if it's too slow, this will not happen. If you rely on getting an
event for *every* change, then your code is broken - libev doesn't guarantee
that (and it's impossible in fact).

> I suspect that this happen because ev_stat_stat() update the ev_stat
> stored stat information, misleading libev to "thinking" everything up to
> the new stat gathered information point has been handled.

Which is trivially true, as it's called when it has detected a change, and
before calling your callback, so it has, in fact, handled everything up to
that point (because this is *before* your callback gets invoked).

If you think the race is in libev and not your code, then you haven't
provided any evidence for that - maybe a testprogram would help, but if
removing the extra stat causes your code to work, it means you have a race
condition.

> Removing the ev_stat_stat() call from the stat_timer_cb() function
> definitely solve the issue.

All you do is decrease the time window for the race condition in your
code.

If the patches changes anything, then you have a bug in your code
(regardless of any other bugs).

> > Did you read the documentation about stat watchers? Naive use will "lose
> > events" and this is not a deficiency in libev, but in the naive usage.
> 
> I've read the "The special problem of stat time resolution" that is
> described in the ev_stat documentation, but this doesn't come into play
> here since the size of the file is changed at each write().

In that case, the bug must be somewhere else - if you read the stat_timer_cb
function you will see that it already calls ev_stat_stat, so another call
does not change anything.

Your confusion likely arises because you think you will get an event for
*every* change, but that's not the case (and cannot ever be). If your code
happens to work with inotify (because it triggers more often), it will
stop working without it, because of that race, or when the system is busy.

libev only guarantees that you get an event if it detects a change to the
previous state, not on every change.

If you disagree, you need to explain which change event you expect to get,
and which you didn't (and _when_, because any changes that happen before
your callback is invoked will obviously not count).

-- 
                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_              http://www.deliantra.net
      ----==-- _       generation
      ---==---(_)__  __ ____  __      Marc Lehmann
      --==---/ / _ \/ // /\ \/ /      schmorp at schmorp.de
      -=====/_/_//_/\_,_/ /_/\_\



More information about the libev mailing list