[PATCH 1 of 3] util: add fswatcher class

Matt Mackall mpm at selenic.com
Fri May 27 07:40:20 CDT 2011

On Fri, 2011-05-27 at 12:22 +0200, Sune Foldager wrote:
> On 2011-05-26 15:38, Matt Mackall wrote:
> >On Thu, 2011-05-26 at 13:06 +0200, Sune Foldager wrote:
> >> # HG changeset patch
> >> # User Sune Foldager <cryo at cyanite.org>
> >> # Date 1306407274 -7200
> >> # Node ID 991245e3b101e911c8fe6c3d75c33676613e5ef5
> >> # Parent  0969d91fad5cad68bcf60f85e2e3286acd11ab52
> >> util: add fswatcher class
> >>
> >> Used to watch files and directories for modifications.
> >
> >Not at all sure about this mtime/ctime comparison business you're doing.
> >Not only is its safety suspect, several filesystems don't have the
> >concept of a ctime.
> Well, the ctime is from time.time() to not really related to the file system.

Ahh, I see. Please, pick another variable name, it's impossible for a
Unix hacker to see mtime and ctime on the same line and not think
they're both referring to stat fields.

> Benoit told me this was the usual way to sidestep the sub-second problem.

Well, no, not exactly. We can't actually trust that system notion of
time is connected to the filesystem's notion of time (see network
filesystem). If all parties don't have a reliable NTP setup, it's quite
easy for causality to appear to be violated. Dirstate does:

        # use the modification time of the newly created temporary file as the  
        # filesystem's notion of 'now'                                          
        now = int(util.fstat(st).st_mtime)

For our watcher purposes, I'm not sure if there's a good way to do this
short of writing a temp file (to the same fs).

And it doesn't really sidestep the problem, it's more a brute-forcing
through. If we write to a repo, update our timestamp, and drop the lock
all in the same second, as we're prone to doing because we're fast, we
can't tell that someone else hasn't come in at the end of that second
and done another write. So the subsecond "trick" is to simply note that
this is possible and force an invalidate. If the invalidate takes less
than the time we would have had to sleep to avoid ambiguity, we win.

However, note that our constraints here are different: we're not writing
our timestamps to a file with a six-year-old disk format. We're just
keeping them in memory. Which means we can take advantage of sub-second
timestamps where available, and we can even look at more stat elements
than dirstate tracks.

> Dirstate tracks and compares mtime and size and contents, that's a difference.
> Size alone is not enough, as an external tool could, in a very contrived
> scenario, go in and modify the repo.

Ok, but no one has ever suggested that size alone was enough. The idea
would be to force a reload if either mtime OR size (OR inode OR ctime,
etc.) changed.

Mathematics is the supreme nostalgia of our time.

More information about the Mercurial-devel mailing list