| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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> |
| 11 #include <aclapi.h> | 11 #include <aclapi.h> |
| 12 #elif defined(OS_POSIX) | 12 #elif defined(OS_POSIX) |
| 13 #include <sys/stat.h> | 13 #include <sys/stat.h> |
| 14 #endif | 14 #endif |
| 15 | 15 |
| 16 #include "base/basictypes.h" | 16 #include "base/basictypes.h" |
| 17 #include "base/bind.h" | 17 #include "base/bind.h" |
| 18 #include "base/bind_helpers.h" |
| 18 #include "base/compiler_specific.h" | 19 #include "base/compiler_specific.h" |
| 19 #include "base/file_path.h" | 20 #include "base/file_path.h" |
| 20 #include "base/file_util.h" | 21 #include "base/file_util.h" |
| 21 #include "base/message_loop.h" | 22 #include "base/message_loop.h" |
| 22 #include "base/message_loop_proxy.h" | 23 #include "base/message_loop_proxy.h" |
| 23 #include "base/path_service.h" | 24 #include "base/path_service.h" |
| 24 #include "base/scoped_temp_dir.h" | 25 #include "base/scoped_temp_dir.h" |
| 25 #include "base/stl_util.h" | 26 #include "base/stl_util.h" |
| 26 #include "base/stringprintf.h" | 27 #include "base/stringprintf.h" |
| 27 #include "base/synchronization/waitable_event.h" | 28 #include "base/synchronization/waitable_event.h" |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 FilePathWatcher watcher; | 253 FilePathWatcher watcher; |
| 253 scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); | 254 scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 254 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get())); | 255 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get())); |
| 255 | 256 |
| 256 // Now make sure we get notified if the file is deleted. | 257 // Now make sure we get notified if the file is deleted. |
| 257 file_util::Delete(test_file(), false); | 258 file_util::Delete(test_file(), false); |
| 258 ASSERT_TRUE(WaitForEvents()); | 259 ASSERT_TRUE(WaitForEvents()); |
| 259 } | 260 } |
| 260 | 261 |
| 261 TEST_F(FilePathWatcherTest, Callback) { | 262 TEST_F(FilePathWatcherTest, Callback) { |
| 262 FilePathWatcher watcher; | 263 FilePathWatcher* watcher = new FilePathWatcher(); |
| 263 bool called_back = false; | 264 bool called_back = false; |
| 264 | 265 |
| 265 MessageLoop* file_loop = file_thread_.message_loop(); | 266 MessageLoop* file_loop = file_thread_.message_loop(); |
| 266 ASSERT_TRUE(file_loop); | 267 ASSERT_TRUE(file_loop); |
| 267 // The callback makes |loop_| quit on file events, and flips |called_back| | 268 // The callback makes |loop_| quit on file events, and flips |called_back| |
| 268 // to true. | 269 // to true. |
| 269 FilePathWatcher::Callback callback = base::Bind( | 270 FilePathWatcher::Callback callback = base::Bind( |
| 270 QuitLoopWatchCallback, &loop_, test_file(), false, &called_back); | 271 QuitLoopWatchCallback, &loop_, test_file(), false, &called_back); |
| 271 | 272 |
| 272 // Start watching on the file thread, and unblock the loop once the callback | 273 // Start watching on the file thread, and unblock the loop once the callback |
| 273 // has been installed. | 274 // has been installed. |
| 274 file_thread_.message_loop_proxy()->PostTaskAndReply( | 275 file_thread_.message_loop_proxy()->PostTaskAndReply( |
| 275 FROM_HERE, | 276 FROM_HERE, |
| 276 base::Bind(SetupWatchCallback, test_file(), &watcher, callback), | 277 base::Bind(SetupWatchCallback, test_file(), watcher, callback), |
| 277 base::Bind(&MessageLoop::Quit, base::Unretained(&loop_))); | 278 base::Bind(&MessageLoop::Quit, base::Unretained(&loop_))); |
| 278 loop_.Run(); | 279 loop_.Run(); |
| 279 | 280 |
| 280 // The watch has been installed. Trigger a file event now, which will unblock | 281 // The watch has been installed. Trigger a file event now, which will unblock |
| 281 // the loop again. | 282 // the loop again. |
| 282 ASSERT_TRUE(WriteFile(test_file(), "content")); | 283 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 283 loop_.Run(); | 284 loop_.Run(); |
| 284 EXPECT_TRUE(called_back); | 285 EXPECT_TRUE(called_back); |
| 286 |
| 287 // Multiple events might have triggered, meaning that multiple |
| 288 // QuitLoopWatchCallback have been posted. The FilePathWatcher can only cancel |
| 289 // on the FILE thread, and thus that callback might still trigger after this |
| 290 // function returns. Make sure the |watcher| is deleted before returning and |
| 291 // destroying |called_back|. |
| 292 // A better fix requires significant changes to the FilePathWatcher. |
| 293 // TODO(joaodasilva): fix the FPW interface. http://crbug.com/145653 |
| 294 file_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, watcher); |
| 295 file_thread_.message_loop_proxy()->PostTaskAndReply( |
| 296 FROM_HERE, |
| 297 base::Bind(base::DoNothing), |
| 298 base::Bind(&MessageLoop::Quit, base::Unretained(&loop_))); |
| 299 loop_.Run(); |
| 285 } | 300 } |
| 286 | 301 |
| 287 // Used by the DeleteDuringNotify test below. | 302 // Used by the DeleteDuringNotify test below. |
| 288 // Deletes the FilePathWatcher when it's notified. | 303 // Deletes the FilePathWatcher when it's notified. |
| 289 class Deleter : public FilePathWatcher::Delegate { | 304 class Deleter : public FilePathWatcher::Delegate { |
| 290 public: | 305 public: |
| 291 Deleter(FilePathWatcher* watcher, MessageLoop* loop) | 306 Deleter(FilePathWatcher* watcher, MessageLoop* loop) |
| 292 : watcher_(watcher), | 307 : watcher_(watcher), |
| 293 loop_(loop) { | 308 loop_(loop) { |
| 294 } | 309 } |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false)); | 835 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false)); |
| 821 ASSERT_TRUE(WaitForEvents()); | 836 ASSERT_TRUE(WaitForEvents()); |
| 822 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true)); | 837 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true)); |
| 823 } | 838 } |
| 824 | 839 |
| 825 #endif // OS_MACOSX | 840 #endif // OS_MACOSX |
| 826 } // namespace | 841 } // namespace |
| 827 | 842 |
| 828 } // namespace files | 843 } // namespace files |
| 829 } // namespace base | 844 } // namespace base |
| OLD | NEW |