1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_WIN_OBJECT_WATCHER_H_ 6 #define BASE_WIN_OBJECT_WATCHER_H_ 7 #pragma once 8 9 #include <windows.h> 10 11 #include "base/base_api.h" 12 #include "base/message_loop.h" 13 14 namespace base { 15 namespace win { 16 17 // A class that provides a means to asynchronously wait for a Windows object to 18 // become signaled. It is an abstraction around RegisterWaitForSingleObject 19 // that provides a notification callback, OnObjectSignaled, that runs back on 20 // the origin thread (i.e., the thread that called StartWatching). 21 // 22 // This class acts like a smart pointer such that when it goes out-of-scope, 23 // UnregisterWaitEx is automatically called, and any in-flight notification is 24 // suppressed. 25 // 26 // Typical usage: 27 // 28 // class MyClass : public base::ObjectWatcher::Delegate { 29 // public: 30 // void DoStuffWhenSignaled(HANDLE object) { 31 // watcher_.StartWatching(object, this); 32 // } 33 // virtual void OnObjectSignaled(HANDLE object) { 34 // // OK, time to do stuff! 35 // } 36 // private: 37 // base::ObjectWatcher watcher_; 38 // }; 39 // 40 // In the above example, MyClass wants to "do stuff" when object becomes 41 // signaled. ObjectWatcher makes this task easy. When MyClass goes out of 42 // scope, the watcher_ will be destroyed, and there is no need to worry about 43 // OnObjectSignaled being called on a deleted MyClass pointer. Easy! 44 // 45 class BASE_API ObjectWatcher : public MessageLoop::DestructionObserver { 46 public: 47 class Delegate { 48 public: 49 virtual ~Delegate() {} 50 // Called from the MessageLoop when a signaled object is detected. To 51 // continue watching the object, AddWatch must be called again. 52 virtual void OnObjectSignaled(HANDLE object) = 0; 53 }; 54 55 ObjectWatcher(); 56 ~ObjectWatcher(); 57 58 // When the object is signaled, the given delegate is notified on the thread 59 // where StartWatching is called. The ObjectWatcher is not responsible for 60 // deleting the delegate. 61 // 62 // Returns true if the watch was started. Otherwise, false is returned. 63 // 64 bool StartWatching(HANDLE object, Delegate* delegate); 65 66 // Stops watching. Does nothing if the watch has already completed. If the 67 // watch is still active, then it is canceled, and the associated delegate is 68 // not notified. 69 // 70 // Returns true if the watch was canceled. Otherwise, false is returned. 71 // 72 bool StopWatching(); 73 74 // Returns the handle of the object being watched, or NULL if the object 75 // watcher is stopped. 76 HANDLE GetWatchedObject(); 77 78 private: 79 // Called on a background thread when done waiting. 80 static void CALLBACK DoneWaiting(void* param, BOOLEAN timed_out); 81 82 // MessageLoop::DestructionObserver implementation: 83 virtual void WillDestroyCurrentMessageLoop(); 84 85 // Internal state. 86 struct Watch; 87 Watch* watch_; 88 89 DISALLOW_COPY_AND_ASSIGN(ObjectWatcher); 90 }; 91 92 } // namespace win 93 } // namespace base 94 95 #endif // BASE_OBJECT_WATCHER_H_ 96