| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |