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

Side by Side Diff: chrome/browser/file_watcher_inotify.cc

Issue 2868114: Rework FileWatcher to avoid race condition upon deletion. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Add missing return... Created 10 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 | « chrome/browser/file_watcher.h ('k') | chrome/browser/file_watcher_mac.cc » ('j') | 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/file_watcher.h" 5 #include "chrome/browser/file_watcher.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <string.h> 8 #include <string.h>
9 #include <sys/inotify.h> 9 #include <sys/inotify.h>
10 #include <sys/ioctl.h> 10 #include <sys/ioctl.h>
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 86
87 // Called for each event coming from the watch. 87 // Called for each event coming from the watch.
88 void OnInotifyEvent(const inotify_event* event); 88 void OnInotifyEvent(const inotify_event* event);
89 89
90 // Start watching |path| for changes and notify |delegate| on each change. 90 // Start watching |path| for changes and notify |delegate| on each change.
91 // Returns true if watch for |path| has been added successfully. 91 // Returns true if watch for |path| has been added successfully.
92 virtual bool Watch(const FilePath& path, FileWatcher::Delegate* delegate); 92 virtual bool Watch(const FilePath& path, FileWatcher::Delegate* delegate);
93 93
94 private: 94 private:
95 // Delegate to notify upon changes. 95 // Delegate to notify upon changes.
96 FileWatcher::Delegate* delegate_; 96 scoped_refptr<FileWatcher::Delegate> delegate_;
97 97
98 // Watch returned by InotifyReader. 98 // Watch returned by InotifyReader.
99 InotifyReader::Watch watch_; 99 InotifyReader::Watch watch_;
100 100
101 // The file we're watching. 101 // The file we're watching.
102 FilePath path_; 102 FilePath path_;
103 103
104 DISALLOW_COPY_AND_ASSIGN(FileWatcherImpl); 104 DISALLOW_COPY_AND_ASSIGN(FileWatcherImpl);
105 }; 105 };
106 106
107 class FileWatcherImplNotifyTask : public Task {
108 public:
109 FileWatcherImplNotifyTask(FileWatcher::Delegate* delegate,
110 const FilePath& path)
111 : delegate_(delegate), path_(path) {
112 }
113
114 virtual void Run() {
115 delegate_->OnFileChanged(path_);
116 }
117
118 private:
119 FileWatcher::Delegate* delegate_;
120 FilePath path_;
121
122 DISALLOW_COPY_AND_ASSIGN(FileWatcherImplNotifyTask);
123 };
124
125 class InotifyReaderTask : public Task { 107 class InotifyReaderTask : public Task {
126 public: 108 public:
127 InotifyReaderTask(InotifyReader* reader, int inotify_fd, int shutdown_fd) 109 InotifyReaderTask(InotifyReader* reader, int inotify_fd, int shutdown_fd)
128 : reader_(reader), 110 : reader_(reader),
129 inotify_fd_(inotify_fd), 111 inotify_fd_(inotify_fd),
130 shutdown_fd_(shutdown_fd) { 112 shutdown_fd_(shutdown_fd) {
131 } 113 }
132 114
133 virtual void Run() { 115 virtual void Run() {
134 while (true) { 116 while (true) {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 Singleton<InotifyReader>::get()->RemoveWatch(watch_, this); 268 Singleton<InotifyReader>::get()->RemoveWatch(watch_, this);
287 } 269 }
288 270
289 void FileWatcherImpl::OnInotifyEvent(const inotify_event* event) { 271 void FileWatcherImpl::OnInotifyEvent(const inotify_event* event) {
290 // Since we're watching the directory, filter out inotify events 272 // Since we're watching the directory, filter out inotify events
291 // if it's not related to the file we're watching. 273 // if it's not related to the file we're watching.
292 if (path_ != path_.DirName().Append(event->name)) 274 if (path_ != path_.DirName().Append(event->name))
293 return; 275 return;
294 276
295 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 277 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
296 new FileWatcherImplNotifyTask(delegate_, path_)); 278 NewRunnableMethod(delegate_.get(), &FileWatcher::Delegate::OnFileChanged,
279 path_));
297 } 280 }
298 281
299 bool FileWatcherImpl::Watch(const FilePath& path, 282 bool FileWatcherImpl::Watch(const FilePath& path,
300 FileWatcher::Delegate* delegate) { 283 FileWatcher::Delegate* delegate) {
301 // Each FileWatcherImpl can only watch one file. 284 // Each FileWatcherImpl can only watch one file.
302 DCHECK(watch_ == InotifyReader::kInvalidWatch); 285 DCHECK(watch_ == InotifyReader::kInvalidWatch);
303 286
304 // It's not possible to watch a file that doesn't exist, so instead, 287 // It's not possible to watch a file that doesn't exist, so instead,
305 // watch the parent directory. 288 // watch the parent directory.
306 if (!file_util::PathExists(path.DirName())) 289 if (!file_util::PathExists(path.DirName()))
307 return false; 290 return false;
308 291
309 delegate_ = delegate; 292 delegate_ = delegate;
310 path_ = path; 293 path_ = path;
311 watch_ = Singleton<InotifyReader>::get()->AddWatch(path.DirName(), this); 294 watch_ = Singleton<InotifyReader>::get()->AddWatch(path.DirName(), this);
312 return watch_ != InotifyReader::kInvalidWatch; 295 return watch_ != InotifyReader::kInvalidWatch;
313 } 296 }
314 297
315 } // namespace 298 } // namespace
316 299
317 FileWatcher::FileWatcher() { 300 FileWatcher::FileWatcher() {
318 impl_ = new FileWatcherImpl(); 301 impl_ = new FileWatcherImpl();
319 } 302 }
OLDNEW
« no previous file with comments | « chrome/browser/file_watcher.h ('k') | chrome/browser/file_watcher_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698