michael@0: // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #ifndef BASE_OBJECT_WATCHER_H_ michael@0: #define BASE_OBJECT_WATCHER_H_ michael@0: michael@0: #include michael@0: #ifdef GetClassName michael@0: #undef GetClassName michael@0: #endif michael@0: michael@0: #include "base/message_loop.h" michael@0: michael@0: namespace base { michael@0: michael@0: // A class that provides a means to asynchronously wait for a Windows object to michael@0: // become signaled. It is an abstraction around RegisterWaitForSingleObject michael@0: // that provides a notification callback, OnObjectSignaled, that runs back on michael@0: // the origin thread (i.e., the thread that called StartWatching). michael@0: // michael@0: // This class acts like a smart pointer such that when it goes out-of-scope, michael@0: // UnregisterWaitEx is automatically called, and any in-flight notification is michael@0: // suppressed. michael@0: // michael@0: // Typical usage: michael@0: // michael@0: // class MyClass : public base::ObjectWatcher::Delegate { michael@0: // public: michael@0: // void DoStuffWhenSignaled(HANDLE object) { michael@0: // watcher_.StartWatching(object, this); michael@0: // } michael@0: // virtual void OnObjectSignaled(HANDLE object) { michael@0: // // OK, time to do stuff! michael@0: // } michael@0: // private: michael@0: // base::ObjectWatcher watcher_; michael@0: // }; michael@0: // michael@0: // In the above example, MyClass wants to "do stuff" when object becomes michael@0: // signaled. ObjectWatcher makes this task easy. When MyClass goes out of michael@0: // scope, the watcher_ will be destroyed, and there is no need to worry about michael@0: // OnObjectSignaled being called on a deleted MyClass pointer. Easy! michael@0: // michael@0: class ObjectWatcher : public MessageLoop::DestructionObserver { michael@0: public: michael@0: class Delegate { michael@0: public: michael@0: virtual ~Delegate() {} michael@0: // Called from the MessageLoop when a signaled object is detected. To michael@0: // continue watching the object, AddWatch must be called again. michael@0: virtual void OnObjectSignaled(HANDLE object) = 0; michael@0: }; michael@0: michael@0: ObjectWatcher(); michael@0: ~ObjectWatcher(); michael@0: michael@0: // When the object is signaled, the given delegate is notified on the thread michael@0: // where StartWatching is called. The ObjectWatcher is not responsible for michael@0: // deleting the delegate. michael@0: // michael@0: // Returns true if the watch was started. Otherwise, false is returned. michael@0: // michael@0: bool StartWatching(HANDLE object, Delegate* delegate); michael@0: michael@0: // Stops watching. Does nothing if the watch has already completed. If the michael@0: // watch is still active, then it is canceled, and the associated delegate is michael@0: // not notified. michael@0: // michael@0: // Returns true if the watch was canceled. Otherwise, false is returned. michael@0: // michael@0: bool StopWatching(); michael@0: michael@0: // Returns the handle of the object being watched, or NULL if the object michael@0: // watcher is stopped. michael@0: HANDLE GetWatchedObject(); michael@0: michael@0: private: michael@0: // Called on a background thread when done waiting. michael@0: static void CALLBACK DoneWaiting(void* param, BOOLEAN timed_out); michael@0: michael@0: // MessageLoop::DestructionObserver implementation: michael@0: virtual void WillDestroyCurrentMessageLoop(); michael@0: michael@0: // Internal state. michael@0: struct Watch; michael@0: Watch* watch_; michael@0: michael@0: DISALLOW_COPY_AND_ASSIGN(ObjectWatcher); michael@0: }; michael@0: michael@0: } // namespace base michael@0: michael@0: #endif // BASE_OBJECT_WATCHER_H_