OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/common/file_path_watcher/file_path_watcher.h" | 5 #include "content/common/file_path_watcher/file_path_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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 // the object appears, and |is_directory| is set when the event refers to a | 91 // the object appears, and |is_directory| is set when the event refers to a |
92 // directory. | 92 // directory. |
93 void OnFilePathChanged(InotifyReader::Watch fired_watch, | 93 void OnFilePathChanged(InotifyReader::Watch fired_watch, |
94 const FilePath::StringType& child, | 94 const FilePath::StringType& child, |
95 bool created, | 95 bool created, |
96 bool is_directory); | 96 bool is_directory); |
97 | 97 |
98 // Start watching |path| for changes and notify |delegate| on each change. | 98 // Start watching |path| for changes and notify |delegate| on each change. |
99 // Returns true if watch for |path| has been added successfully. | 99 // Returns true if watch for |path| has been added successfully. |
100 virtual bool Watch(const FilePath& path, | 100 virtual bool Watch(const FilePath& path, |
101 FilePathWatcher::Delegate* delegate, | 101 FilePathWatcher::Delegate* delegate) OVERRIDE; |
102 base::MessageLoopProxy* loop) OVERRIDE; | |
103 | 102 |
104 // Cancel the watch. This unregisters the instance with InotifyReader. | 103 // Cancel the watch. This unregisters the instance with InotifyReader. |
105 virtual void Cancel() OVERRIDE; | 104 virtual void Cancel() OVERRIDE; |
106 | 105 |
107 // Deletion of the FilePathWatcher will call Cancel() to dispose of this | 106 // Deletion of the FilePathWatcher will call Cancel() to dispose of this |
108 // object in the right thread. This also observes destruction of the required | 107 // object in the right thread. This also observes destruction of the required |
109 // cleanup thread, in case it quits before Cancel() is called. | 108 // cleanup thread, in case it quits before Cancel() is called. |
110 virtual void WillDestroyCurrentMessageLoop() OVERRIDE; | 109 virtual void WillDestroyCurrentMessageLoop() OVERRIDE; |
111 | 110 |
112 private: | 111 private: |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 // Check whether a path component of |target_| changed. | 337 // Check whether a path component of |target_| changed. |
339 bool change_on_target_path = child.empty() || child == watch_entry->subdir_; | 338 bool change_on_target_path = child.empty() || child == watch_entry->subdir_; |
340 | 339 |
341 // Check whether the change references |target_| or a direct child. | 340 // Check whether the change references |target_| or a direct child. |
342 DCHECK(watch_entry->subdir_.empty() || (watch_entry + 1) != watches_.end()); | 341 DCHECK(watch_entry->subdir_.empty() || (watch_entry + 1) != watches_.end()); |
343 bool target_changed = watch_entry->subdir_.empty() || | 342 bool target_changed = watch_entry->subdir_.empty() || |
344 (watch_entry->subdir_ == child && (++watch_entry)->subdir_.empty()); | 343 (watch_entry->subdir_ == child && (++watch_entry)->subdir_.empty()); |
345 | 344 |
346 // Update watches if a directory component of the |target_| path (dis)appears. | 345 // Update watches if a directory component of the |target_| path (dis)appears. |
347 if (is_directory && change_on_target_path && !UpdateWatches()) { | 346 if (is_directory && change_on_target_path && !UpdateWatches()) { |
348 delegate_->OnError(); | 347 delegate_->OnFilePathError(target_); |
349 return; | 348 return; |
350 } | 349 } |
351 | 350 |
352 // Report the following events: | 351 // Report the following events: |
353 // - The target or a direct child of the target got changed (in case the | 352 // - The target or a direct child of the target got changed (in case the |
354 // watched path refers to a directory). | 353 // watched path refers to a directory). |
355 // - One of the parent directories got moved or deleted, since the target | 354 // - One of the parent directories got moved or deleted, since the target |
356 // disappears in this case. | 355 // disappears in this case. |
357 // - One of the parent directories appears. The event corresponding to the | 356 // - One of the parent directories appears. The event corresponding to the |
358 // target appearing might have been missed in this case, so recheck. | 357 // target appearing might have been missed in this case, so recheck. |
359 if (target_changed || | 358 if (target_changed || |
360 (change_on_target_path && !created) || | 359 (change_on_target_path && !created) || |
361 (change_on_target_path && file_util::PathExists(target_))) { | 360 (change_on_target_path && file_util::PathExists(target_))) { |
362 delegate_->OnFilePathChanged(target_); | 361 delegate_->OnFilePathChanged(target_); |
363 } | 362 } |
364 } | 363 } |
365 | 364 |
366 bool FilePathWatcherImpl::Watch(const FilePath& path, | 365 bool FilePathWatcherImpl::Watch(const FilePath& path, |
367 FilePathWatcher::Delegate* delegate, | 366 FilePathWatcher::Delegate* delegate) { |
368 base::MessageLoopProxy*) { | |
369 DCHECK(target_.empty()); | 367 DCHECK(target_.empty()); |
370 DCHECK(MessageLoopForIO::current()); | 368 DCHECK(MessageLoopForIO::current()); |
371 | 369 |
372 set_message_loop(base::MessageLoopProxy::CreateForCurrentThread()); | 370 set_message_loop(base::MessageLoopProxy::CreateForCurrentThread()); |
373 delegate_ = delegate; | 371 delegate_ = delegate; |
374 target_ = path; | 372 target_ = path; |
375 MessageLoop::current()->AddDestructionObserver(this); | 373 MessageLoop::current()->AddDestructionObserver(this); |
376 | 374 |
377 std::vector<FilePath::StringType> comps; | 375 std::vector<FilePath::StringType> comps; |
378 target_.GetComponents(&comps); | 376 target_.GetComponents(&comps); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 } | 447 } |
450 | 448 |
451 return true; | 449 return true; |
452 } | 450 } |
453 | 451 |
454 } // namespace | 452 } // namespace |
455 | 453 |
456 FilePathWatcher::FilePathWatcher() { | 454 FilePathWatcher::FilePathWatcher() { |
457 impl_ = new FilePathWatcherImpl(); | 455 impl_ = new FilePathWatcherImpl(); |
458 } | 456 } |
OLD | NEW |