Commit 29ec5c1e authored by jhawkins@chromium.org's avatar jhawkins@chromium.org

base::Bind: Convert FilePathWatcher.

BUG=none
TEST=none

R=willchan@chromium.org

Review URL: http://codereview.chromium.org/8677015

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111405 0039d316-1c4b-4281-b951-d872f2087c98
parent c2b1b307
...@@ -17,6 +17,12 @@ FilePathWatcher::~FilePathWatcher() { ...@@ -17,6 +17,12 @@ FilePathWatcher::~FilePathWatcher() {
impl_->Cancel(); impl_->Cancel();
} }
// static
void FilePathWatcher::CancelWatch(
const scoped_refptr<PlatformDelegate>& delegate) {
delegate->CancelOnMessageLoopThread();
}
bool FilePathWatcher::Watch(const FilePath& path, Delegate* delegate) { bool FilePathWatcher::Watch(const FilePath& path, Delegate* delegate) {
DCHECK(path.IsAbsolute()); DCHECK(path.IsAbsolute());
return impl_->Watch(path, delegate); return impl_->Watch(path, delegate);
......
...@@ -40,37 +40,9 @@ class BASE_EXPORT FilePathWatcher { ...@@ -40,37 +40,9 @@ class BASE_EXPORT FilePathWatcher {
virtual void OnFilePathError(const FilePath& path) {} virtual void OnFilePathError(const FilePath& path) {}
}; };
FilePathWatcher();
~FilePathWatcher();
// Register interest in any changes on |path|. OnPathChanged will be called
// back for each change. Returns true on success.
// 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) WARN_UNUSED_RESULT;
class PlatformDelegate;
// 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 {
public:
CancelTask(PlatformDelegate* delegate): delegate_(delegate) {}
virtual ~CancelTask() {
delegate_->CancelOnMessageLoopThread();
}
virtual void Run() OVERRIDE {
delegate_->CancelOnMessageLoopThread();
}
private:
scoped_refptr<PlatformDelegate> delegate_;
DISALLOW_COPY_AND_ASSIGN(CancelTask);
};
// Used internally to encapsulate different members on different platforms. // Used internally to encapsulate different members on different platforms.
// TODO(jhawkins): Move this into its own file. Also fix the confusing naming
// wrt Delegate vs PlatformDelegate.
class PlatformDelegate : public base::RefCountedThreadSafe<PlatformDelegate> { class PlatformDelegate : public base::RefCountedThreadSafe<PlatformDelegate> {
public: public:
PlatformDelegate(); PlatformDelegate();
...@@ -85,6 +57,8 @@ class BASE_EXPORT FilePathWatcher { ...@@ -85,6 +57,8 @@ class BASE_EXPORT FilePathWatcher {
virtual void Cancel() = 0; virtual void Cancel() = 0;
protected: protected:
friend class FilePathWatcher;
virtual ~PlatformDelegate(); virtual ~PlatformDelegate();
// Stop watching. This is only called on the thread of the appropriate // Stop watching. This is only called on the thread of the appropriate
...@@ -111,12 +85,25 @@ class BASE_EXPORT FilePathWatcher { ...@@ -111,12 +85,25 @@ class BASE_EXPORT FilePathWatcher {
private: private:
friend class base::RefCountedThreadSafe<PlatformDelegate>; friend class base::RefCountedThreadSafe<PlatformDelegate>;
friend class CancelTask;
scoped_refptr<base::MessageLoopProxy> message_loop_; scoped_refptr<base::MessageLoopProxy> message_loop_;
bool cancelled_; bool cancelled_;
}; };
FilePathWatcher();
~FilePathWatcher();
// A callback that always cleans up the PlatformDelegate, either when executed
// or when deleted without having been executed at all, as can happen during
// shutdown.
static void CancelWatch(const scoped_refptr<PlatformDelegate>& delegate);
// Register interest in any changes on |path|. OnPathChanged will be called
// back for each change. Returns true on success.
// 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) WARN_UNUSED_RESULT;
private: private:
scoped_refptr<PlatformDelegate> impl_; scoped_refptr<PlatformDelegate> impl_;
......
...@@ -72,7 +72,7 @@ class NotificationCollector ...@@ -72,7 +72,7 @@ class NotificationCollector
// Check whether all delegates have been signaled. // Check whether all delegates have been signaled.
if (signaled_ == delegates_) if (signaled_ == delegates_)
loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
} }
// Set of registered delegates. // Set of registered delegates.
...@@ -113,34 +113,14 @@ class TestDelegate : public FilePathWatcher::Delegate { ...@@ -113,34 +113,14 @@ class TestDelegate : public FilePathWatcher::Delegate {
DISALLOW_COPY_AND_ASSIGN(TestDelegate); DISALLOW_COPY_AND_ASSIGN(TestDelegate);
}; };
// A helper class for setting up watches on the file thread. void SetupWatchCallback(const FilePath& target,
class SetupWatchTask : public Task { FilePathWatcher* watcher,
public: FilePathWatcher::Delegate* delegate,
SetupWatchTask(const FilePath& target, bool* result,
FilePathWatcher* watcher, base::WaitableEvent* completion) {
FilePathWatcher::Delegate* delegate, *result = watcher->Watch(target, delegate);
bool* result, completion->Signal();
base::WaitableEvent* completion) }
: target_(target),
watcher_(watcher),
delegate_(delegate),
result_(result),
completion_(completion) {}
void Run() {
*result_ = watcher_->Watch(target_, delegate_);
completion_->Signal();
}
private:
const FilePath target_;
FilePathWatcher* watcher_;
FilePathWatcher::Delegate* delegate_;
bool* result_;
base::WaitableEvent* completion_;
DISALLOW_COPY_AND_ASSIGN(SetupWatchTask);
};
class FilePathWatcherTest : public testing::Test { class FilePathWatcherTest : public testing::Test {
public: public:
...@@ -182,12 +162,10 @@ class FilePathWatcherTest : public testing::Test { ...@@ -182,12 +162,10 @@ class FilePathWatcherTest : public testing::Test {
FilePathWatcher::Delegate* delegate) WARN_UNUSED_RESULT { FilePathWatcher::Delegate* delegate) WARN_UNUSED_RESULT {
base::WaitableEvent completion(false, false); base::WaitableEvent completion(false, false);
bool result; bool result;
file_thread_.message_loop_proxy()->PostTask(FROM_HERE, file_thread_.message_loop_proxy()->PostTask(
new SetupWatchTask(target, FROM_HERE,
watcher, base::Bind(SetupWatchCallback, target, watcher,
delegate, make_scoped_refptr(delegate), &result, &completion));
&result,
&completion));
completion.Wait(); completion.Wait();
return result; return result;
} }
...@@ -266,7 +244,7 @@ class Deleter : public FilePathWatcher::Delegate { ...@@ -266,7 +244,7 @@ class Deleter : public FilePathWatcher::Delegate {
virtual void OnFilePathChanged(const FilePath& path) { virtual void OnFilePathChanged(const FilePath& path) {
watcher_.reset(); watcher_.reset();
loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
} }
scoped_ptr<FilePathWatcher> watcher_; scoped_ptr<FilePathWatcher> watcher_;
...@@ -778,7 +756,7 @@ TEST_F(FilePathWatcherTest, DirAttributesChanged) { ...@@ -778,7 +756,7 @@ TEST_F(FilePathWatcherTest, DirAttributesChanged) {
// to access the file. // to access the file.
ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, false)); ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, false));
loop_.PostDelayedTask(FROM_HERE, loop_.PostDelayedTask(FROM_HERE,
new MessageLoop::QuitTask, MessageLoop::QuitClosure(),
TestTimeouts::tiny_timeout_ms()); TestTimeouts::tiny_timeout_ms());
ASSERT_FALSE(WaitForEvents()); ASSERT_FALSE(WaitForEvents());
ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, true)); ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, true));
......
...@@ -412,7 +412,8 @@ void FilePathWatcherImpl::Cancel() { ...@@ -412,7 +412,8 @@ void FilePathWatcherImpl::Cancel() {
// Switch to the message_loop_ if necessary so we can access |watches_|. // Switch to the message_loop_ if necessary so we can access |watches_|.
if (!message_loop()->BelongsToCurrentThread()) { if (!message_loop()->BelongsToCurrentThread()) {
message_loop()->PostTask(FROM_HERE, message_loop()->PostTask(FROM_HERE,
new FilePathWatcher::CancelTask(this)); base::Bind(&FilePathWatcher::CancelWatch,
make_scoped_refptr(this)));
} else { } else {
CancelOnMessageLoopThread(); CancelOnMessageLoopThread();
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "base/files/file_path_watcher.h" #include "base/files/file_path_watcher.h"
#include "base/bind.h"
#include "base/file_path.h" #include "base/file_path.h"
#include "base/file_util.h" #include "base/file_util.h"
#include "base/logging.h" #include "base/logging.h"
...@@ -104,7 +105,8 @@ void FilePathWatcherImpl::Cancel() { ...@@ -104,7 +105,8 @@ void FilePathWatcherImpl::Cancel() {
// Switch to the file thread if necessary so we can stop |watcher_|. // Switch to the file thread if necessary so we can stop |watcher_|.
if (!message_loop()->BelongsToCurrentThread()) { if (!message_loop()->BelongsToCurrentThread()) {
message_loop()->PostTask(FROM_HERE, message_loop()->PostTask(FROM_HERE,
new FilePathWatcher::CancelTask(this)); base::Bind(&FilePathWatcher::CancelWatch,
make_scoped_refptr(this)));
} else { } else {
CancelOnMessageLoopThread(); CancelOnMessageLoopThread();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment