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

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

Issue 2236523002: Remove base::internal::InotifyReader's destructor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove shutdown_pipe_ Created 4 years, 4 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>
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 59
60 // Callback for InotifyReaderTask. 60 // Callback for InotifyReaderTask.
61 void OnInotifyEvent(const inotify_event* event); 61 void OnInotifyEvent(const inotify_event* event);
62 62
63 private: 63 private:
64 friend struct DefaultLazyInstanceTraits<InotifyReader>; 64 friend struct DefaultLazyInstanceTraits<InotifyReader>;
65 65
66 typedef std::set<FilePathWatcherImpl*> WatcherSet; 66 typedef std::set<FilePathWatcherImpl*> WatcherSet;
67 67
68 InotifyReader(); 68 InotifyReader();
69 ~InotifyReader(); 69 // There is no destructor because |g_inotify_reader| is a
70 // base::LazyInstace::Leaky object. Having a destructor causes build
71 // issues with GCC 6 (http://crbug.com/636346).
70 72
71 // We keep track of which delegates want to be notified on which watches. 73 // We keep track of which delegates want to be notified on which watches.
72 hash_map<Watch, WatcherSet> watchers_; 74 hash_map<Watch, WatcherSet> watchers_;
73 75
74 // Lock to protect watchers_. 76 // Lock to protect watchers_.
75 Lock lock_; 77 Lock lock_;
76 78
77 // Separate thread on which we run blocking read for inotify events. 79 // Separate thread on which we run blocking read for inotify events.
78 Thread thread_; 80 Thread thread_;
79 81
80 // File descriptor returned by inotify_init. 82 // File descriptor returned by inotify_init.
81 const int inotify_fd_; 83 const int inotify_fd_;
82 84
83 // Use self-pipe trick to unblock select during shutdown.
84 int shutdown_pipe_[2];
85
86 // Flag set to true when startup was successful. 85 // Flag set to true when startup was successful.
87 bool valid_; 86 bool valid_;
88 87
89 DISALLOW_COPY_AND_ASSIGN(InotifyReader); 88 DISALLOW_COPY_AND_ASSIGN(InotifyReader);
90 }; 89 };
91 90
92 class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate, 91 class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate,
93 public MessageLoop::DestructionObserver { 92 public MessageLoop::DestructionObserver {
94 public: 93 public:
95 FilePathWatcherImpl(); 94 FilePathWatcherImpl();
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 // starting at the root directory. The last entry corresponds to the watch for 186 // starting at the root directory. The last entry corresponds to the watch for
188 // |target_| and always stores an empty next component name in |subdir|. 187 // |target_| and always stores an empty next component name in |subdir|.
189 WatchVector watches_; 188 WatchVector watches_;
190 189
191 hash_map<InotifyReader::Watch, FilePath> recursive_paths_by_watch_; 190 hash_map<InotifyReader::Watch, FilePath> recursive_paths_by_watch_;
192 std::map<FilePath, InotifyReader::Watch> recursive_watches_by_path_; 191 std::map<FilePath, InotifyReader::Watch> recursive_watches_by_path_;
193 192
194 DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl); 193 DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl);
195 }; 194 };
196 195
197 void InotifyReaderCallback(InotifyReader* reader, int inotify_fd, 196 void InotifyReaderCallback(InotifyReader* reader, int inotify_fd) {
198 int shutdown_fd) {
199 // Make sure the file descriptors are good for use with select(). 197 // Make sure the file descriptors are good for use with select().
200 CHECK_LE(0, inotify_fd); 198 CHECK_LE(0, inotify_fd);
201 CHECK_GT(FD_SETSIZE, inotify_fd); 199 CHECK_GT(FD_SETSIZE, inotify_fd);
202 CHECK_LE(0, shutdown_fd);
203 CHECK_GT(FD_SETSIZE, shutdown_fd);
204 200
205 trace_event::TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop(); 201 trace_event::TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop();
206 202
207 while (true) { 203 while (true) {
208 fd_set rfds; 204 fd_set rfds;
209 FD_ZERO(&rfds); 205 FD_ZERO(&rfds);
210 FD_SET(inotify_fd, &rfds); 206 FD_SET(inotify_fd, &rfds);
211 FD_SET(shutdown_fd, &rfds);
212 207
213 // Wait until some inotify events are available. 208 // Wait until some inotify events are available.
214 int select_result = 209 int select_result =
215 HANDLE_EINTR(select(std::max(inotify_fd, shutdown_fd) + 1, 210 HANDLE_EINTR(select(inotify_fd + 1, &rfds, NULL, NULL, NULL));
216 &rfds, NULL, NULL, NULL));
217 if (select_result < 0) { 211 if (select_result < 0) {
218 DPLOG(WARNING) << "select failed"; 212 DPLOG(WARNING) << "select failed";
219 return; 213 return;
220 } 214 }
221 215
222 if (FD_ISSET(shutdown_fd, &rfds))
223 return;
224
225 // Adjust buffer size to current event queue size. 216 // Adjust buffer size to current event queue size.
226 int buffer_size; 217 int buffer_size;
227 int ioctl_result = HANDLE_EINTR(ioctl(inotify_fd, FIONREAD, 218 int ioctl_result = HANDLE_EINTR(ioctl(inotify_fd, FIONREAD,
228 &buffer_size)); 219 &buffer_size));
229 220
230 if (ioctl_result != 0) { 221 if (ioctl_result != 0) {
231 DPLOG(WARNING) << "ioctl failed"; 222 DPLOG(WARNING) << "ioctl failed";
232 return; 223 return;
233 } 224 }
234 225
(...skipping 21 matching lines...) Expand all
256 static LazyInstance<InotifyReader>::Leaky g_inotify_reader = 247 static LazyInstance<InotifyReader>::Leaky g_inotify_reader =
257 LAZY_INSTANCE_INITIALIZER; 248 LAZY_INSTANCE_INITIALIZER;
258 249
259 InotifyReader::InotifyReader() 250 InotifyReader::InotifyReader()
260 : thread_("inotify_reader"), 251 : thread_("inotify_reader"),
261 inotify_fd_(inotify_init()), 252 inotify_fd_(inotify_init()),
262 valid_(false) { 253 valid_(false) {
263 if (inotify_fd_ < 0) 254 if (inotify_fd_ < 0)
264 PLOG(ERROR) << "inotify_init() failed"; 255 PLOG(ERROR) << "inotify_init() failed";
265 256
266 shutdown_pipe_[0] = -1; 257 if (inotify_fd_ >= 0 && thread_.Start()) {
267 shutdown_pipe_[1] = -1;
268 if (inotify_fd_ >= 0 && pipe(shutdown_pipe_) == 0 && thread_.Start()) {
269 thread_.task_runner()->PostTask( 258 thread_.task_runner()->PostTask(
270 FROM_HERE, 259 FROM_HERE,
271 Bind(&InotifyReaderCallback, this, inotify_fd_, shutdown_pipe_[0])); 260 Bind(&InotifyReaderCallback, this, inotify_fd_));
272 valid_ = true; 261 valid_ = true;
273 } 262 }
274 } 263 }
275 264
276 InotifyReader::~InotifyReader() {
277 if (valid_) {
278 // Write to the self-pipe so that the select call in InotifyReaderTask
279 // returns.
280 ssize_t ret = HANDLE_EINTR(write(shutdown_pipe_[1], "", 1));
281 DPCHECK(ret > 0);
282 DCHECK_EQ(ret, 1);
283 thread_.Stop();
284 }
285 if (inotify_fd_ >= 0)
286 close(inotify_fd_);
287 if (shutdown_pipe_[0] >= 0)
288 close(shutdown_pipe_[0]);
289 if (shutdown_pipe_[1] >= 0)
290 close(shutdown_pipe_[1]);
291 }
292
293 InotifyReader::Watch InotifyReader::AddWatch( 265 InotifyReader::Watch InotifyReader::AddWatch(
294 const FilePath& path, FilePathWatcherImpl* watcher) { 266 const FilePath& path, FilePathWatcherImpl* watcher) {
295 if (!valid_) 267 if (!valid_)
296 return kInvalidWatch; 268 return kInvalidWatch;
297 269
298 AutoLock auto_lock(lock_); 270 AutoLock auto_lock(lock_);
299 271
300 Watch watch = inotify_add_watch(inotify_fd_, path.value().c_str(), 272 Watch watch = inotify_add_watch(inotify_fd_, path.value().c_str(),
301 IN_ATTRIB | IN_CREATE | IN_DELETE | 273 IN_ATTRIB | IN_CREATE | IN_DELETE |
302 IN_CLOSE_WRITE | IN_MOVE | 274 IN_CLOSE_WRITE | IN_MOVE |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 return watches_.back().subdir.empty(); 652 return watches_.back().subdir.empty();
681 } 653 }
682 654
683 } // namespace 655 } // namespace
684 656
685 FilePathWatcher::FilePathWatcher() { 657 FilePathWatcher::FilePathWatcher() {
686 impl_ = new FilePathWatcherImpl(); 658 impl_ = new FilePathWatcherImpl();
687 } 659 }
688 660
689 } // namespace base 661 } // 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