summaryrefslogtreecommitdiffstats
path: root/base/directory_watcher_win.cc
diff options
context:
space:
mode:
authorevanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-17 02:45:56 +0000
committerevanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-17 02:45:56 +0000
commit9e8d4f92df67dd8d4c8d4097035aaf6279fe84ba (patch)
treeed08cb639f07c35da5eabc10f4519cb88c10ae64 /base/directory_watcher_win.cc
parent9b6633c2877f08381f84f60a33a5eeb9bfa0f3e0 (diff)
downloadchromium_src-9e8d4f92df67dd8d4c8d4097035aaf6279fe84ba.zip
chromium_src-9e8d4f92df67dd8d4c8d4097035aaf6279fe84ba.tar.gz
chromium_src-9e8d4f92df67dd8d4c8d4097035aaf6279fe84ba.tar.bz2
Add a DirectoryWatcher class, allowing objects to be notified whenever
a directory's contents change. Review URL: http://codereview.chromium.org/6377 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3504 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/directory_watcher_win.cc')
-rw-r--r--base/directory_watcher_win.cc86
1 files changed, 86 insertions, 0 deletions
diff --git a/base/directory_watcher_win.cc b/base/directory_watcher_win.cc
new file mode 100644
index 0000000..cdaec39
--- /dev/null
+++ b/base/directory_watcher_win.cc
@@ -0,0 +1,86 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/directory_watcher.h"
+
+#include "base/file_path.h"
+#include "base/object_watcher.h"
+
+// Private implementation class implementing the behavior of DirectoryWatcher.
+class DirectoryWatcher::Impl : public base::RefCounted<DirectoryWatcher::Impl>,
+ public base::ObjectWatcher::Delegate {
+ public:
+ Impl(DirectoryWatcher::Delegate* delegate)
+ : delegate_(delegate), handle_(INVALID_HANDLE_VALUE) {}
+ ~Impl();
+
+ // Register interest in any changes in |path|.
+ // Returns false on error.
+ bool Watch(const FilePath& path);
+
+ // Callback from MessageLoopForIO.
+ virtual void OnObjectSignaled(HANDLE object);
+
+ private:
+ // Delegate to notify upon changes.
+ DirectoryWatcher::Delegate* delegate_;
+ // Path we're watching (passed to delegate).
+ FilePath path_;
+ // Handle for FindFirstChangeNotification.
+ HANDLE handle_;
+ // ObjectWatcher to watch handle_ for events.
+ base::ObjectWatcher watcher_;
+};
+
+DirectoryWatcher::Impl::~Impl() {
+ if (handle_ != INVALID_HANDLE_VALUE) {
+ watcher_.StopWatching();
+ FindCloseChangeNotification(handle_);
+ }
+}
+
+bool DirectoryWatcher::Impl::Watch(const FilePath& path) {
+ DCHECK(path_.value().empty()); // Can only watch one path.
+
+ handle_ = FindFirstChangeNotification(
+ path.value().c_str(),
+ FALSE, // Don't watch subtree.
+ FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE |
+ FILE_NOTIFY_CHANGE_LAST_WRITE);
+ if (handle_ == INVALID_HANDLE_VALUE) {
+ NOTREACHED();
+ return false;
+ }
+
+ path_ = path;
+ watcher_.StartWatching(handle_, this);
+
+ return true;
+}
+
+void DirectoryWatcher::Impl::OnObjectSignaled(HANDLE object) {
+ DCHECK(object == handle_);
+ // Make sure we stay alive through the body of this function.
+ scoped_refptr<DirectoryWatcher::Impl> keep_alive(this);
+
+ delegate_->OnDirectoryChanged(path_);
+
+ // Register for more notifications on file change.
+ BOOL ok = FindNextChangeNotification(object);
+ DCHECK(ok);
+ watcher_.StartWatching(object, this);
+}
+
+DirectoryWatcher::DirectoryWatcher() {
+}
+
+DirectoryWatcher::~DirectoryWatcher() {
+ // Declared in .cc file for access to ~DirectoryWatcher::Impl.
+}
+
+bool DirectoryWatcher::Watch(const FilePath& path,
+ Delegate* delegate) {
+ impl_ = new DirectoryWatcher::Impl(delegate);
+ return impl_->Watch(path);
+}