Chromium Code Reviews| Index: content/common/file_path_watcher/file_path_watcher.h |
| diff --git a/content/common/file_path_watcher/file_path_watcher.h b/content/common/file_path_watcher/file_path_watcher.h |
| index 7c784a8bc44fa9777ace5c93f5d1957069a2ee85..940e948bed67ebe7b38dd21b57f6e74c98980c22 100644 |
| --- a/content/common/file_path_watcher/file_path_watcher.h |
| +++ b/content/common/file_path_watcher/file_path_watcher.h |
| @@ -40,22 +40,33 @@ class FilePathWatcher { |
| // by the Mac implementation right now, and must be backed by a CFRunLoop |
| // based MessagePump. This is usually going to be a MessageLoop of type |
| // TYPE_UI. |
| + // OnFilePathChanged() will be called on the same thread as Watch() is called, |
| + // which should have a MessageLoop of TYPE_IO. |
| bool Watch(const FilePath& path, |
| Delegate* delegate, |
| base::MessageLoopProxy* loop) WARN_UNUSED_RESULT; |
| class PlatformDelegate; |
| - // Traits for PlatformDelegate, which must delete itself on the IO message |
| - // loop that Watch was called from. |
| - struct DeletePlatformDelegate { |
| - static void Destruct(const PlatformDelegate* delegate); |
| + // A custom Task that always cleans up the PlatformDelegate, either when |
| + // executed or when deleted without having been executed at all, as can |
| + // happen during shutdown. |
| + class CancelTask: public Task { |
|
Mattias Nissler (ping if slow)
2011/03/22 17:23:44
missing space before :
Joao da Silva
2011/03/22 17:42:33
Done.
|
| + public: |
| + CancelTask(PlatformDelegate* delegate): delegate_(delegate) {} |
| + virtual ~CancelTask() { |
| + delegate_->CancelOnMessageLoopThread(); |
| + } |
| + |
| + virtual void Run() { |
| + delegate_->CancelOnMessageLoopThread(); |
| + } |
| + private: |
| + scoped_refptr<PlatformDelegate> delegate_; |
|
Mattias Nissler (ping if slow)
2011/03/22 17:23:44
DISALLOW_COPY_AND_ASSIGN
Joao da Silva
2011/03/22 17:42:33
Done.
|
| }; |
| // Used internally to encapsulate different members on different platforms. |
| - class PlatformDelegate |
| - : public base::RefCountedThreadSafe<PlatformDelegate, |
| - DeletePlatformDelegate> { |
| + class PlatformDelegate: public base::RefCountedThreadSafe<PlatformDelegate> { |
| public: |
| PlatformDelegate(); |
| @@ -70,14 +81,17 @@ class FilePathWatcher { |
| // Stop watching. This is called from FilePathWatcher's dtor in order to |
| // allow to shut down properly while the object is still alive. |
| + // It can be called from any thread. |
| virtual void Cancel() = 0; |
| protected: |
| - friend class DeleteTask<PlatformDelegate>; |
| - friend struct DeletePlatformDelegate; |
| - |
| virtual ~PlatformDelegate(); |
| + // Stop watching. This is only called on the thread of the appropriate |
| + // message loop. Since it can also be called more than once, it should |
| + // check |is_cancelled()| to avoid duplicate work. |
| + virtual void CancelOnMessageLoopThread() = 0; |
| + |
| scoped_refptr<base::MessageLoopProxy> message_loop() const { |
| return message_loop_; |
| } |
| @@ -86,8 +100,21 @@ class FilePathWatcher { |
| message_loop_ = loop; |
| } |
| + // Must be called before the PlatformDelegate is deleted. |
| + void set_cancelled() { |
| + cancelled_ = true; |
| + } |
| + |
| + bool is_cancelled() const { |
| + return cancelled_; |
| + } |
| + |
| private: |
| + friend class base::RefCountedThreadSafe<PlatformDelegate>; |
| + friend class CancelTask; |
| + |
| scoped_refptr<base::MessageLoopProxy> message_loop_; |
| + bool cancelled_; |
| }; |
| private: |