OLD | NEW |
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 <unistd.h> | 13 #include <unistd.h> |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
16 #include <map> | 16 #include <map> |
17 #include <memory> | 17 #include <memory> |
18 #include <set> | 18 #include <set> |
| 19 #include <unordered_map> |
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/files/file_enumerator.h" | 24 #include "base/files/file_enumerator.h" |
25 #include "base/files/file_path.h" | 25 #include "base/files/file_path.h" |
26 #include "base/files/file_util.h" | 26 #include "base/files/file_util.h" |
27 #include "base/lazy_instance.h" | 27 #include "base/lazy_instance.h" |
28 #include "base/location.h" | 28 #include "base/location.h" |
29 #include "base/logging.h" | 29 #include "base/logging.h" |
30 #include "base/macros.h" | 30 #include "base/macros.h" |
31 #include "base/memory/ptr_util.h" | 31 #include "base/memory/ptr_util.h" |
32 #include "base/memory/weak_ptr.h" | 32 #include "base/memory/weak_ptr.h" |
33 #include "base/posix/eintr_wrapper.h" | 33 #include "base/posix/eintr_wrapper.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 friend struct LazyInstanceTraitsBase<InotifyReader>; | 66 friend struct LazyInstanceTraitsBase<InotifyReader>; |
67 | 67 |
68 typedef std::set<FilePathWatcherImpl*> WatcherSet; | 68 typedef std::set<FilePathWatcherImpl*> WatcherSet; |
69 | 69 |
70 InotifyReader(); | 70 InotifyReader(); |
71 // There is no destructor because |g_inotify_reader| is a | 71 // There is no destructor because |g_inotify_reader| is a |
72 // base::LazyInstace::Leaky object. Having a destructor causes build | 72 // base::LazyInstace::Leaky object. Having a destructor causes build |
73 // issues with GCC 6 (http://crbug.com/636346). | 73 // issues with GCC 6 (http://crbug.com/636346). |
74 | 74 |
75 // We keep track of which delegates want to be notified on which watches. | 75 // We keep track of which delegates want to be notified on which watches. |
76 hash_map<Watch, WatcherSet> watchers_; | 76 std::unordered_map<Watch, WatcherSet> watchers_; |
77 | 77 |
78 // Lock to protect watchers_. | 78 // Lock to protect watchers_. |
79 Lock lock_; | 79 Lock lock_; |
80 | 80 |
81 // Separate thread on which we run blocking read for inotify events. | 81 // Separate thread on which we run blocking read for inotify events. |
82 Thread thread_; | 82 Thread thread_; |
83 | 83 |
84 // File descriptor returned by inotify_init. | 84 // File descriptor returned by inotify_init. |
85 const int inotify_fd_; | 85 const int inotify_fd_; |
86 | 86 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 // The file or directory we're supposed to watch. | 177 // The file or directory we're supposed to watch. |
178 FilePath target_; | 178 FilePath target_; |
179 | 179 |
180 bool recursive_; | 180 bool recursive_; |
181 | 181 |
182 // The vector of watches and next component names for all path components, | 182 // The vector of watches and next component names for all path components, |
183 // starting at the root directory. The last entry corresponds to the watch for | 183 // starting at the root directory. The last entry corresponds to the watch for |
184 // |target_| and always stores an empty next component name in |subdir|. | 184 // |target_| and always stores an empty next component name in |subdir|. |
185 WatchVector watches_; | 185 WatchVector watches_; |
186 | 186 |
187 hash_map<InotifyReader::Watch, FilePath> recursive_paths_by_watch_; | 187 std::unordered_map<InotifyReader::Watch, FilePath> recursive_paths_by_watch_; |
188 std::map<FilePath, InotifyReader::Watch> recursive_watches_by_path_; | 188 std::map<FilePath, InotifyReader::Watch> recursive_watches_by_path_; |
189 | 189 |
190 WeakPtrFactory<FilePathWatcherImpl> weak_factory_; | 190 WeakPtrFactory<FilePathWatcherImpl> weak_factory_; |
191 | 191 |
192 DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl); | 192 DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl); |
193 }; | 193 }; |
194 | 194 |
195 void InotifyReaderCallback(InotifyReader* reader, int inotify_fd) { | 195 void InotifyReaderCallback(InotifyReader* reader, int inotify_fd) { |
196 // Make sure the file descriptors are good for use with select(). | 196 // Make sure the file descriptors are good for use with select(). |
197 CHECK_LE(0, inotify_fd); | 197 CHECK_LE(0, inotify_fd); |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 DCHECK(!ContainsKey(recursive_paths_by_watch_, watch)); | 589 DCHECK(!ContainsKey(recursive_paths_by_watch_, watch)); |
590 DCHECK(!ContainsKey(recursive_watches_by_path_, path)); | 590 DCHECK(!ContainsKey(recursive_watches_by_path_, path)); |
591 recursive_paths_by_watch_[watch] = path; | 591 recursive_paths_by_watch_[watch] = path; |
592 recursive_watches_by_path_[path] = watch; | 592 recursive_watches_by_path_[path] = watch; |
593 } | 593 } |
594 | 594 |
595 void FilePathWatcherImpl::RemoveRecursiveWatches() { | 595 void FilePathWatcherImpl::RemoveRecursiveWatches() { |
596 if (!recursive_) | 596 if (!recursive_) |
597 return; | 597 return; |
598 | 598 |
599 for (hash_map<InotifyReader::Watch, FilePath>::const_iterator it = | 599 for (const auto& it : recursive_paths_by_watch_) |
600 recursive_paths_by_watch_.begin(); | 600 g_inotify_reader.Get().RemoveWatch(it.first, this); |
601 it != recursive_paths_by_watch_.end(); | 601 |
602 ++it) { | |
603 g_inotify_reader.Get().RemoveWatch(it->first, this); | |
604 } | |
605 recursive_paths_by_watch_.clear(); | 602 recursive_paths_by_watch_.clear(); |
606 recursive_watches_by_path_.clear(); | 603 recursive_watches_by_path_.clear(); |
607 } | 604 } |
608 | 605 |
609 void FilePathWatcherImpl::AddWatchForBrokenSymlink(const FilePath& path, | 606 void FilePathWatcherImpl::AddWatchForBrokenSymlink(const FilePath& path, |
610 WatchEntry* watch_entry) { | 607 WatchEntry* watch_entry) { |
611 DCHECK_EQ(InotifyReader::kInvalidWatch, watch_entry->watch); | 608 DCHECK_EQ(InotifyReader::kInvalidWatch, watch_entry->watch); |
612 FilePath link; | 609 FilePath link; |
613 if (!ReadSymbolicLink(path, &link)) | 610 if (!ReadSymbolicLink(path, &link)) |
614 return; | 611 return; |
(...skipping 29 matching lines...) Expand all Loading... |
644 } | 641 } |
645 | 642 |
646 } // namespace | 643 } // namespace |
647 | 644 |
648 FilePathWatcher::FilePathWatcher() { | 645 FilePathWatcher::FilePathWatcher() { |
649 sequence_checker_.DetachFromSequence(); | 646 sequence_checker_.DetachFromSequence(); |
650 impl_ = MakeUnique<FilePathWatcherImpl>(); | 647 impl_ = MakeUnique<FilePathWatcherImpl>(); |
651 } | 648 } |
652 | 649 |
653 } // namespace base | 650 } // namespace base |
OLD | NEW |