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

Side by Side Diff: base/files/file_path_watcher_linux.cc

Issue 2308413002: Only update watches when directories change. (Closed)
Patch Set: Created 4 years, 3 months 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/files/file_path_watcher.h" 5 #include "base/files/file_path_watcher.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <string.h> 9 #include <string.h>
10 #include <sys/inotify.h> 10 #include <sys/inotify.h>
11 #include <sys/ioctl.h> 11 #include <sys/ioctl.h>
12 #include <sys/select.h> 12 #include <sys/select.h>
13 #include <sys/stat.h>
13 #include <unistd.h> 14 #include <unistd.h>
14 15
15 #include <algorithm> 16 #include <algorithm>
16 #include <map> 17 #include <map>
17 #include <memory> 18 #include <memory>
18 #include <set> 19 #include <set>
19 #include <utility> 20 #include <utility>
20 #include <vector> 21 #include <vector>
21 22
22 #include "base/bind.h" 23 #include "base/bind.h"
23 #include "base/containers/hash_tables.h" 24 #include "base/containers/hash_tables.h"
24 #include "base/files/file_enumerator.h" 25 #include "base/files/file_enumerator.h"
25 #include "base/files/file_path.h" 26 #include "base/files/file_path.h"
26 #include "base/files/file_util.h" 27 #include "base/files/file_util.h"
27 #include "base/lazy_instance.h" 28 #include "base/lazy_instance.h"
28 #include "base/location.h" 29 #include "base/location.h"
29 #include "base/logging.h" 30 #include "base/logging.h"
30 #include "base/macros.h" 31 #include "base/macros.h"
31 #include "base/posix/eintr_wrapper.h" 32 #include "base/posix/eintr_wrapper.h"
32 #include "base/single_thread_task_runner.h" 33 #include "base/single_thread_task_runner.h"
33 #include "base/stl_util.h" 34 #include "base/stl_util.h"
34 #include "base/synchronization/lock.h" 35 #include "base/synchronization/lock.h"
35 #include "base/threading/thread.h" 36 #include "base/threading/thread.h"
36 #include "base/threading/thread_task_runner_handle.h" 37 #include "base/threading/thread_task_runner_handle.h"
38 #include "base/time/time.h"
37 #include "base/trace_event/trace_event.h" 39 #include "base/trace_event/trace_event.h"
38 40
39 namespace base { 41 namespace base {
40 42
41 namespace { 43 namespace {
42 44
43 class FilePathWatcherImpl; 45 class FilePathWatcherImpl;
44 46
45 // Singleton to manage all inotify watches. 47 // Singleton to manage all inotify watches.
46 // TODO(tony): It would be nice if this wasn't a singleton. 48 // TODO(tony): It would be nice if this wasn't a singleton.
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 // Report the following events: 398 // Report the following events:
397 // - The target or a direct child of the target got changed (in case the 399 // - The target or a direct child of the target got changed (in case the
398 // watched path refers to a directory). 400 // watched path refers to a directory).
399 // - One of the parent directories got moved or deleted, since the target 401 // - One of the parent directories got moved or deleted, since the target
400 // disappears in this case. 402 // disappears in this case.
401 // - One of the parent directories appears. The event corresponding to 403 // - One of the parent directories appears. The event corresponding to
402 // the target appearing might have been missed in this case, so recheck. 404 // the target appearing might have been missed in this case, so recheck.
403 if (target_changed || 405 if (target_changed ||
404 (change_on_target_path && deleted) || 406 (change_on_target_path && deleted) ||
405 (change_on_target_path && created && PathExists(target_))) { 407 (change_on_target_path && created && PathExists(target_))) {
406 if (!did_update) { 408 struct stat child_stat;
409 stat(target_.Append(watch_entry.subdir).Append(child).value().c_str(),
410 &child_stat);
411 if (!did_update && S_ISDIR(child_stat.st_mode)) {
407 UpdateRecursiveWatches(fired_watch, is_dir); 412 UpdateRecursiveWatches(fired_watch, is_dir);
408 did_update = true; 413 did_update = true;
409 } 414 }
410 callback_.Run(target_, false /* error */); 415 callback_.Run(target_, false /* error */);
411 return; 416 return;
412 } 417 }
413 } 418 }
414 419
415 if (ContainsKey(recursive_paths_by_watch_, fired_watch)) { 420 if (ContainsKey(recursive_paths_by_watch_, fired_watch)) {
416 if (!did_update) 421 if (!did_update)
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 } 527 }
523 528
524 // Check to see if this is a forced update or if some component of |target_| 529 // Check to see if this is a forced update or if some component of |target_|
525 // has changed. For these cases, redo the watches for |target_| and below. 530 // has changed. For these cases, redo the watches for |target_| and below.
526 if (!ContainsKey(recursive_paths_by_watch_, fired_watch)) { 531 if (!ContainsKey(recursive_paths_by_watch_, fired_watch)) {
527 UpdateRecursiveWatchesForPath(target_); 532 UpdateRecursiveWatchesForPath(target_);
528 return; 533 return;
529 } 534 }
530 535
531 // Underneath |target_|, only directory changes trigger watch updates. 536 // Underneath |target_|, only directory changes trigger watch updates.
532 if (!is_dir) 537 if (!is_dir)
Shuhei Takahashi 2016/09/05 10:48:09 Hmm, is this check insufficient?
dspaid 2016/09/05 12:57:22 Good catch. It should be, but observations sugges
533 return; 538 return;
534 539
535 const FilePath& changed_dir = recursive_paths_by_watch_[fired_watch]; 540 const FilePath& changed_dir = recursive_paths_by_watch_[fired_watch];
536 541
537 std::map<FilePath, InotifyReader::Watch>::iterator start_it = 542 std::map<FilePath, InotifyReader::Watch>::iterator start_it =
538 recursive_watches_by_path_.lower_bound(changed_dir); 543 recursive_watches_by_path_.lower_bound(changed_dir);
539 std::map<FilePath, InotifyReader::Watch>::iterator end_it = start_it; 544 std::map<FilePath, InotifyReader::Watch>::iterator end_it = start_it;
540 for (; end_it != recursive_watches_by_path_.end(); ++end_it) { 545 for (; end_it != recursive_watches_by_path_.end(); ++end_it) {
541 const FilePath& cur_path = end_it->first; 546 const FilePath& cur_path = end_it->first;
542 if (!changed_dir.IsParent(cur_path)) 547 if (!changed_dir.IsParent(cur_path))
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 return watches_.back().subdir.empty(); 657 return watches_.back().subdir.empty();
653 } 658 }
654 659
655 } // namespace 660 } // namespace
656 661
657 FilePathWatcher::FilePathWatcher() { 662 FilePathWatcher::FilePathWatcher() {
658 impl_ = new FilePathWatcherImpl(); 663 impl_ = new FilePathWatcherImpl();
659 } 664 }
660 665
661 } // namespace base 666 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698