summaryrefslogtreecommitdiffstats
path: root/base/object_watcher.h
diff options
context:
space:
mode:
authordarin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-04 17:46:47 +0000
committerdarin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-04 17:46:47 +0000
commitb49054718ac2c49f629427c41a4ff2a6ba4bdb09 (patch)
tree0611d3d1d64574356dd3705ee66f7309a251bec3 /base/object_watcher.h
parent1c15248a5f6ffd48c99bca9d2fbd6d4b375e991c (diff)
downloadchromium_src-b49054718ac2c49f629427c41a4ff2a6ba4bdb09.zip
chromium_src-b49054718ac2c49f629427c41a4ff2a6ba4bdb09.tar.gz
chromium_src-b49054718ac2c49f629427c41a4ff2a6ba4bdb09.tar.bz2
Revise the ObjectWatcher API to be one-to-one with the object being watched. This greatly simplifies the implementation and API.
Now consumers can use ObjectWatcher as a "smart pointer" class, which automatically cleans-up after itself when it goes out of scope. I also switched away from the Task based API to one that is more compatible with MessageLoop::WatchObject. That allows me to make minimal changes to existing code, and it also means that consumers do not have to allocate Task objects to use this API. In this CL, I included changes to make a couple consumers use ObjectWatcher instead of ML::WatchObject. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@322 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/object_watcher.h')
-rw-r--r--base/object_watcher.h76
1 files changed, 50 insertions, 26 deletions
diff --git a/base/object_watcher.h b/base/object_watcher.h
index 58431b1..de4816a 100644
--- a/base/object_watcher.h
+++ b/base/object_watcher.h
@@ -32,53 +32,77 @@
#include <windows.h>
-#include <map>
-
-#include "base/linked_ptr.h"
-#include "base/tracked.h"
-
-class Task;
+#include "base/basictypes.h"
namespace base {
-// A class that enables support for asynchronously waiting for Windows objects
-// to become signaled. Supports waiting on more than 64 objects.
+// A class that provides a means to asynchronously wait for a Windows object to
+// become signaled. It is an abstraction around RegisterWaitForSingleObject
+// that provides a notification callback, OnObjectSignaled, that runs back on
+// the origin thread (i.e., the thread that called StartWatching).
+//
+// This class acts like a smart pointer such that when it goes out-of-scope,
+// UnregisterWaitEx is automatically called, and any in-flight notification is
+// suppressed.
+//
+// Typical usage:
+//
+// class MyClass : public base::ObjectWatcher::Delegate {
+// public:
+// void DoStuffWhenSignaled(HANDLE object) {
+// watcher_.StartWatching(object, this);
+// }
+// virtual void OnObjectSignaled(HANDLE object) {
+// // OK, time to do stuff!
+// }
+// private:
+// base::ObjectWatcher watcher_;
+// };
+//
+// In the above example, MyClass wants to "do stuff" when object becomes
+// signaled. ObjectWatcher makes this task easy. When MyClass goes out of
+// scope, the watcher_ will be destroyed, and there is no need to worry about
+// OnObjectSignaled being called on a deleted MyClass pointer. Easy!
+//
class ObjectWatcher {
public:
+ class Delegate {
+ public:
+ virtual ~Delegate() {}
+ // Called from the MessageLoop when a signaled object is detected. To
+ // continue watching the object, AddWatch must be called again.
+ virtual void OnObjectSignaled(HANDLE object) = 0;
+ };
+
ObjectWatcher();
~ObjectWatcher();
- // When the object is signaled, the given task is run on the thread where
- // Watch is called. The ObjectWatcher assumes ownership of the task and
- // will ensure that it gets deleted eventually.
+ // When the object is signaled, the given delegate is notified on the thread
+ // where StartWatching is called. The ObjectWatcher is not responsible for
+ // deleting the delegate.
//
- // NOTE: It is an error to call this method on an object that is already
- // being watched by this ObjectWatcher.
+ // Returns true if the watch was started. Otherwise, false is returned.
//
- // Returns true if the watch was added. Otherwise, false is returned.
- //
- bool AddWatch(const tracked_objects::Location& from_here, HANDLE object,
- Task* task);
+ bool StartWatching(HANDLE object, Delegate* delegate);
- // Stops watching the given object. Does nothing if the watch has already
- // completed. If the watch is still active, then it is canceled, and the
- // associated task is deleted.
+ // Stops watching. Does nothing if the watch has already completed. If the
+ // watch is still active, then it is canceled, and the associated delegate is
+ // not notified.
//
// Returns true if the watch was canceled. Otherwise, false is returned.
//
- bool CancelWatch(HANDLE object);
+ bool StopWatching();
private:
// Called on a background thread when done waiting.
static void CALLBACK DoneWaiting(void* param, BOOLEAN timed_out);
- // Passed as the param argument to the above methods.
+ // Internal state.
struct Watch;
+ Watch* watch_;
- typedef std::map<HANDLE, linked_ptr<Watch>> WatchMap;
- WatchMap watches_;
-};
-
+ DISALLOW_COPY_AND_ASSIGN(ObjectWatcher);
+};
} // namespace base
#endif // BASE_OBJECT_WATCHER_H_