| 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 "base/files/file_path_watcher.h" | 5 #include "base/files/file_path_watcher.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
| 10 #include <windows.h> | 10 #include <windows.h> |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 } | 65 } |
| 66 | 66 |
| 67 private: | 67 private: |
| 68 void RecordChange(TestDelegate* delegate) { | 68 void RecordChange(TestDelegate* delegate) { |
| 69 ASSERT_TRUE(loop_->BelongsToCurrentThread()); | 69 ASSERT_TRUE(loop_->BelongsToCurrentThread()); |
| 70 ASSERT_TRUE(delegates_.count(delegate)); | 70 ASSERT_TRUE(delegates_.count(delegate)); |
| 71 signaled_.insert(delegate); | 71 signaled_.insert(delegate); |
| 72 | 72 |
| 73 // Check whether all delegates have been signaled. | 73 // Check whether all delegates have been signaled. |
| 74 if (signaled_ == delegates_) | 74 if (signaled_ == delegates_) |
| 75 loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 75 loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 76 } | 76 } |
| 77 | 77 |
| 78 // Set of registered delegates. | 78 // Set of registered delegates. |
| 79 std::set<TestDelegate*> delegates_; | 79 std::set<TestDelegate*> delegates_; |
| 80 | 80 |
| 81 // Set of signaled delegates. | 81 // Set of signaled delegates. |
| 82 std::set<TestDelegate*> signaled_; | 82 std::set<TestDelegate*> signaled_; |
| 83 | 83 |
| 84 // The loop we should break after all delegates signaled. | 84 // The loop we should break after all delegates signaled. |
| 85 scoped_refptr<base::MessageLoopProxy> loop_; | 85 scoped_refptr<base::MessageLoopProxy> loop_; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 106 virtual void OnFilePathError(const FilePath& path) { | 106 virtual void OnFilePathError(const FilePath& path) { |
| 107 ADD_FAILURE() << "Error " << path.value(); | 107 ADD_FAILURE() << "Error " << path.value(); |
| 108 } | 108 } |
| 109 | 109 |
| 110 private: | 110 private: |
| 111 scoped_refptr<NotificationCollector> collector_; | 111 scoped_refptr<NotificationCollector> collector_; |
| 112 | 112 |
| 113 DISALLOW_COPY_AND_ASSIGN(TestDelegate); | 113 DISALLOW_COPY_AND_ASSIGN(TestDelegate); |
| 114 }; | 114 }; |
| 115 | 115 |
| 116 // A helper class for setting up watches on the file thread. | 116 void SetupWatchCallback(const FilePath& target, |
| 117 class SetupWatchTask : public Task { | 117 FilePathWatcher* watcher, |
| 118 public: | 118 FilePathWatcher::Delegate* delegate, |
| 119 SetupWatchTask(const FilePath& target, | 119 bool* result, |
| 120 FilePathWatcher* watcher, | 120 base::WaitableEvent* completion) { |
| 121 FilePathWatcher::Delegate* delegate, | 121 *result = watcher->Watch(target, delegate); |
| 122 bool* result, | 122 completion->Signal(); |
| 123 base::WaitableEvent* completion) | 123 } |
| 124 : target_(target), | |
| 125 watcher_(watcher), | |
| 126 delegate_(delegate), | |
| 127 result_(result), | |
| 128 completion_(completion) {} | |
| 129 | |
| 130 void Run() { | |
| 131 *result_ = watcher_->Watch(target_, delegate_); | |
| 132 completion_->Signal(); | |
| 133 } | |
| 134 | |
| 135 private: | |
| 136 const FilePath target_; | |
| 137 FilePathWatcher* watcher_; | |
| 138 FilePathWatcher::Delegate* delegate_; | |
| 139 bool* result_; | |
| 140 base::WaitableEvent* completion_; | |
| 141 | |
| 142 DISALLOW_COPY_AND_ASSIGN(SetupWatchTask); | |
| 143 }; | |
| 144 | 124 |
| 145 class FilePathWatcherTest : public testing::Test { | 125 class FilePathWatcherTest : public testing::Test { |
| 146 public: | 126 public: |
| 147 FilePathWatcherTest() | 127 FilePathWatcherTest() |
| 148 : file_thread_("FilePathWatcherTest") {} | 128 : file_thread_("FilePathWatcherTest") {} |
| 149 | 129 |
| 150 virtual ~FilePathWatcherTest() {} | 130 virtual ~FilePathWatcherTest() {} |
| 151 | 131 |
| 152 protected: | 132 protected: |
| 153 virtual void SetUp() { | 133 virtual void SetUp() { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 175 int write_size = file_util::WriteFile(file, content.c_str(), | 155 int write_size = file_util::WriteFile(file, content.c_str(), |
| 176 content.length()); | 156 content.length()); |
| 177 return write_size == static_cast<int>(content.length()); | 157 return write_size == static_cast<int>(content.length()); |
| 178 } | 158 } |
| 179 | 159 |
| 180 bool SetupWatch(const FilePath& target, | 160 bool SetupWatch(const FilePath& target, |
| 181 FilePathWatcher* watcher, | 161 FilePathWatcher* watcher, |
| 182 FilePathWatcher::Delegate* delegate) WARN_UNUSED_RESULT { | 162 FilePathWatcher::Delegate* delegate) WARN_UNUSED_RESULT { |
| 183 base::WaitableEvent completion(false, false); | 163 base::WaitableEvent completion(false, false); |
| 184 bool result; | 164 bool result; |
| 185 file_thread_.message_loop_proxy()->PostTask(FROM_HERE, | 165 file_thread_.message_loop_proxy()->PostTask( |
| 186 new SetupWatchTask(target, | 166 FROM_HERE, |
| 187 watcher, | 167 base::Bind(SetupWatchCallback, target, watcher, |
| 188 delegate, | 168 make_scoped_refptr(delegate), &result, &completion)); |
| 189 &result, | |
| 190 &completion)); | |
| 191 completion.Wait(); | 169 completion.Wait(); |
| 192 return result; | 170 return result; |
| 193 } | 171 } |
| 194 | 172 |
| 195 bool WaitForEvents() WARN_UNUSED_RESULT { | 173 bool WaitForEvents() WARN_UNUSED_RESULT { |
| 196 collector_->Reset(); | 174 collector_->Reset(); |
| 197 loop_.Run(); | 175 loop_.Run(); |
| 198 return collector_->Success(); | 176 return collector_->Success(); |
| 199 } | 177 } |
| 200 | 178 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 // Deletes the FilePathWatcher when it's notified. | 237 // Deletes the FilePathWatcher when it's notified. |
| 260 class Deleter : public FilePathWatcher::Delegate { | 238 class Deleter : public FilePathWatcher::Delegate { |
| 261 public: | 239 public: |
| 262 Deleter(FilePathWatcher* watcher, MessageLoop* loop) | 240 Deleter(FilePathWatcher* watcher, MessageLoop* loop) |
| 263 : watcher_(watcher), | 241 : watcher_(watcher), |
| 264 loop_(loop) { | 242 loop_(loop) { |
| 265 } | 243 } |
| 266 | 244 |
| 267 virtual void OnFilePathChanged(const FilePath& path) { | 245 virtual void OnFilePathChanged(const FilePath& path) { |
| 268 watcher_.reset(); | 246 watcher_.reset(); |
| 269 loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 247 loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 270 } | 248 } |
| 271 | 249 |
| 272 scoped_ptr<FilePathWatcher> watcher_; | 250 scoped_ptr<FilePathWatcher> watcher_; |
| 273 MessageLoop* loop_; | 251 MessageLoop* loop_; |
| 274 }; | 252 }; |
| 275 | 253 |
| 276 // Verify that deleting a watcher during the callback doesn't crash. | 254 // Verify that deleting a watcher during the callback doesn't crash. |
| 277 TEST_F(FilePathWatcherTest, DeleteDuringNotify) { | 255 TEST_F(FilePathWatcherTest, DeleteDuringNotify) { |
| 278 FilePathWatcher* watcher = new FilePathWatcher; | 256 FilePathWatcher* watcher = new FilePathWatcher; |
| 279 // Takes ownership of watcher. | 257 // Takes ownership of watcher. |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 ASSERT_TRUE(WriteFile(test_file, "content")); | 749 ASSERT_TRUE(WriteFile(test_file, "content")); |
| 772 | 750 |
| 773 FilePathWatcher watcher; | 751 FilePathWatcher watcher; |
| 774 scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); | 752 scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 775 ASSERT_TRUE(SetupWatch(test_file, &watcher, delegate.get())); | 753 ASSERT_TRUE(SetupWatch(test_file, &watcher, delegate.get())); |
| 776 | 754 |
| 777 // We should not get notified in this case as it hasn't affected our ability | 755 // We should not get notified in this case as it hasn't affected our ability |
| 778 // to access the file. | 756 // to access the file. |
| 779 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, false)); | 757 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, false)); |
| 780 loop_.PostDelayedTask(FROM_HERE, | 758 loop_.PostDelayedTask(FROM_HERE, |
| 781 new MessageLoop::QuitTask, | 759 MessageLoop::QuitClosure(), |
| 782 TestTimeouts::tiny_timeout_ms()); | 760 TestTimeouts::tiny_timeout_ms()); |
| 783 ASSERT_FALSE(WaitForEvents()); | 761 ASSERT_FALSE(WaitForEvents()); |
| 784 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, true)); | 762 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, true)); |
| 785 | 763 |
| 786 // We should get notified in this case because filepathwatcher can no | 764 // We should get notified in this case because filepathwatcher can no |
| 787 // longer access the file | 765 // longer access the file |
| 788 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false)); | 766 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false)); |
| 789 ASSERT_TRUE(WaitForEvents()); | 767 ASSERT_TRUE(WaitForEvents()); |
| 790 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true)); | 768 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true)); |
| 791 } | 769 } |
| 792 | 770 |
| 793 #endif // OS_MACOSX | 771 #endif // OS_MACOSX |
| 794 } // namespace | 772 } // namespace |
| 795 | 773 |
| 796 } // namespace files | 774 } // namespace files |
| 797 } // namespace base | 775 } // namespace base |
| OLD | NEW |