Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(824)

Unified Diff: base/files/file_path_watcher_linux.cc

Issue 822713002: Update from https://crrev.com/309415 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/files/file_path_watcher_linux.cc
diff --git a/base/files/file_path_watcher_linux.cc b/base/files/file_path_watcher_linux.cc
index 4078920aac985a4ea183b14b3bf2014583297197..36ee66c30a716ce5051487cedb8903922b50e20b 100644
--- a/base/files/file_path_watcher_linux.cc
+++ b/base/files/file_path_watcher_linux.cc
@@ -125,10 +125,13 @@ class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate,
// cleanup thread, in case it quits before Cancel() is called.
void WillDestroyCurrentMessageLoop() override;
- // Inotify watches are installed for all directory components of |target_|. A
- // WatchEntry instance holds the watch descriptor for a component and the
- // subdirectory for that identifies the next component. If a symbolic link
- // is being watched, the target of the link is also kept.
+ // Inotify watches are installed for all directory components of |target_|.
+ // A WatchEntry instance holds:
+ // - |watch|: the watch descriptor for a component.
+ // - |subdir|: the subdirectory that identifies the next component.
+ // - For the last component, there is no next component, so it is empty.
+ // - |linkname|: the target of the symlink.
+ // - Only if the target being watched is a symbolic link.
struct WatchEntry {
explicit WatchEntry(const FilePath::StringType& dirname)
: watch(InotifyReader::kInvalidWatch),
@@ -381,11 +384,31 @@ void FilePathWatcherImpl::OnFilePathChanged(InotifyReader::Watch fired_watch,
(child == watch_entry.subdir);
// Check if the change references |target_| or a direct child of |target_|.
- bool is_watch_for_target = watch_entry.subdir.empty();
- bool target_changed =
- (is_watch_for_target && (child == watch_entry.linkname)) ||
- (is_watch_for_target && watch_entry.linkname.empty()) ||
- (watch_entry.subdir == child && watches_[i + 1].subdir.empty());
+ bool target_changed;
+ if (watch_entry.subdir.empty()) {
+ // The fired watch is for a WatchEntry without a subdir. Thus for a given
+ // |target_| = "/path/to/foo", this is for "foo". Here, check either:
+ // - the target has no symlink: it is the target and it changed.
+ // - the target has a symlink, and it matches |child|.
+ target_changed = (watch_entry.linkname.empty() ||
+ child == watch_entry.linkname);
+ } else {
+ // The fired watch is for a WatchEntry with a subdir. Thus for a given
+ // |target_| = "/path/to/foo", this is for {"/", "/path", "/path/to"}.
+ // So we can safely access the next WatchEntry since we have not reached
+ // the end yet. Check |watch_entry| is for "/path/to", i.e. the next
+ // element is "foo".
+ bool next_watch_may_be_for_target = watches_[i + 1].subdir.empty();
+ if (next_watch_may_be_for_target) {
+ // The current |watch_entry| is for "/path/to", so check if the |child|
+ // that changed is "foo".
+ target_changed = watch_entry.subdir == child;
+ } else {
+ // The current |watch_entry| is not for "/path/to", so the next entry
+ // cannot be "foo". Thus |target_| has not changed.
+ target_changed = false;
+ }
+ }
// Update watches if a directory component of the |target_| path
// (dis)appears. Note that we don't add the additional restriction of

Powered by Google App Engine
This is Rietveld 408576698