diff options
author | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-04 17:46:47 +0000 |
---|---|---|
committer | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-04 17:46:47 +0000 |
commit | b49054718ac2c49f629427c41a4ff2a6ba4bdb09 (patch) | |
tree | 0611d3d1d64574356dd3705ee66f7309a251bec3 /base/object_watcher.h | |
parent | 1c15248a5f6ffd48c99bca9d2fbd6d4b375e991c (diff) | |
download | chromium_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.h | 76 |
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_ |