| Index: base/files/file_path_watcher_win.cc
|
| diff --git a/base/files/file_path_watcher_win.cc b/base/files/file_path_watcher_win.cc
|
| index 65c13dae74abf1194da34ca80d7278d235e60339..fba6625fb8c3dcb5faa9f48a6dd3d2b67ba6894a 100644
|
| --- a/base/files/file_path_watcher_win.cc
|
| +++ b/base/files/file_path_watcher_win.cc
|
| @@ -10,7 +10,7 @@
|
| #include "base/files/file_util.h"
|
| #include "base/logging.h"
|
| #include "base/macros.h"
|
| -#include "base/memory/ref_counted.h"
|
| +#include "base/memory/ptr_util.h"
|
| #include "base/threading/sequenced_task_runner_handle.h"
|
| #include "base/time/time.h"
|
| #include "base/win/object_watcher.h"
|
| @@ -25,6 +25,7 @@ class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate,
|
| FilePathWatcherImpl()
|
| : handle_(INVALID_HANDLE_VALUE),
|
| recursive_watch_(false) {}
|
| + ~FilePathWatcherImpl() override;
|
|
|
| // FilePathWatcher::PlatformDelegate:
|
| bool Watch(const FilePath& path,
|
| @@ -36,8 +37,6 @@ class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate,
|
| void OnObjectSignaled(HANDLE object) override;
|
|
|
| private:
|
| - ~FilePathWatcherImpl() override {}
|
| -
|
| // Setup a watch handle for directory |dir|. Set |recursive| to true to watch
|
| // the directory sub trees. Returns true if no fatal error occurs. |handle|
|
| // will receive the handle value if |dir| is watchable, otherwise
|
| @@ -58,6 +57,9 @@ class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate,
|
| // Path we're supposed to watch (passed to callback).
|
| FilePath target_;
|
|
|
| + // Set to true in the destructor.
|
| + bool* was_deleted_ptr_ = nullptr;
|
| +
|
| // Handle for FindFirstChangeNotification.
|
| HANDLE handle_;
|
|
|
| @@ -78,6 +80,12 @@ class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate,
|
| DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl);
|
| };
|
|
|
| +FilePathWatcherImpl::~FilePathWatcherImpl() {
|
| + DCHECK(!task_runner() || task_runner()->RunsTasksOnCurrentThread());
|
| + if (was_deleted_ptr_)
|
| + *was_deleted_ptr_ = true;
|
| +}
|
| +
|
| bool FilePathWatcherImpl::Watch(const FilePath& path,
|
| bool recursive,
|
| const FilePathWatcher::Callback& callback) {
|
| @@ -119,9 +127,12 @@ void FilePathWatcherImpl::Cancel() {
|
| }
|
|
|
| void FilePathWatcherImpl::OnObjectSignaled(HANDLE object) {
|
| - DCHECK(object == handle_);
|
| - // Make sure we stay alive through the body of this function.
|
| - scoped_refptr<FilePathWatcherImpl> keep_alive(this);
|
| + DCHECK(task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK_EQ(object, handle_);
|
| + DCHECK(!was_deleted_ptr_);
|
| +
|
| + bool was_deleted = false;
|
| + was_deleted_ptr_ = &was_deleted;
|
|
|
| if (!UpdateWatch()) {
|
| callback_.Run(target_, true /* error */);
|
| @@ -171,8 +182,10 @@ void FilePathWatcherImpl::OnObjectSignaled(HANDLE object) {
|
| }
|
|
|
| // The watch may have been cancelled by the callback.
|
| - if (handle_ != INVALID_HANDLE_VALUE)
|
| + if (!was_deleted) {
|
| watcher_.StartWatchingOnce(handle_, this);
|
| + was_deleted_ptr_ = nullptr;
|
| + }
|
| }
|
|
|
| // static
|
| @@ -269,7 +282,7 @@ void FilePathWatcherImpl::DestroyWatch() {
|
|
|
| FilePathWatcher::FilePathWatcher() {
|
| sequence_checker_.DetachFromSequence();
|
| - impl_ = new FilePathWatcherImpl();
|
| + impl_ = MakeUnique<FilePathWatcherImpl>();
|
| }
|
|
|
| } // namespace base
|
|
|