Skip to content

Commit

Permalink
don't recrawl if a stale watch descriptor is found
Browse files Browse the repository at this point in the history
Summary: I believe this is the correct fix.

Test Plan:
`make integration`, and hgwatchman's test suite -- made sure we never recrawled. Also ran `hg update .~10000` in a large repo -- we'd just about always recrawl without this change. With this change we never recrawled.

Finally, as a sanity check, compared the output of `find -type f` and a watchman query for all files right after the update. Saw that except files in `.hg` there were no discrepancies.

Reviewers: wez

Reviewed By: wez

Subscribers: dreiss

Differential Revision: https://phabricator.fb.com/D1488238
  • Loading branch information
sunshowers committed Aug 10, 2014
1 parent 76d2f05 commit 98cee62
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions root.c
Original file line number Diff line number Diff line change
Expand Up @@ -1322,19 +1322,22 @@ static void crawler(w_root_t *root, w_string_t *dir_name,
/* make sure we're watching this guy */
#if HAVE_INOTIFY_INIT
{
// We've found that directories have had stale file descriptors
// occasionally, so call this unconditionally
// The directory might be different since the last time we looked at it, so
// call inotify_add_watch unconditionally.
int newwd = inotify_add_watch(root->infd, path, WATCHMAN_INOTIFY_MASK);
if (newwd == -1) {
handle_open_errno(root, dir, now, "inotify_add_watch", errno);
return;
} else if (dir->wd != -1 && dir->wd != newwd) {
// stale watch descriptor
w_log(W_LOG_ERR, "watch descriptor for %s should have been %d, is %d\n",
path, dir->wd, newwd);
w_root_schedule_recrawl(root, "stale watch descriptor found");
return;
} else if (dir->wd == -1) {
// This can happen when a directory is deleted and then recreated very
// soon afterwards. e.g. dir->wd is 100, but newwd is 200. We'll still
// expect old events to come in for the directory or its children, so
// blackhole those. stop_watching_dir will mark dir->wd as -1, so the
// condition right below will be true.
stop_watching_dir(root, dir);
}

if (dir->wd == -1) {
w_log(W_LOG_DBG, "watch_dir(%s)\n", path);
dir->wd = newwd;
// record mapping
Expand Down

0 comments on commit 98cee62

Please sign in to comment.