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 14namespace base { 15namespace 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// 45class 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