blob: 3a0b9a9757e60104124a53905ba9ceb2f8e266fb [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// Copyright (c) 2006-2008 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.
darin@google.com6a4581b2008-08-02 06:04:03 +09004
5#ifndef BASE_OBJECT_WATCHER_H_
6#define BASE_OBJECT_WATCHER_H_
7
8#include <windows.h>
9
darin@google.com965e5342008-08-06 08:16:41 +090010#include "base/message_loop.h"
darin@google.com6a4581b2008-08-02 06:04:03 +090011
12namespace base {
13
darin@google.com18f923a2008-08-05 02:46:47 +090014// A class that provides a means to asynchronously wait for a Windows object to
15// become signaled. It is an abstraction around RegisterWaitForSingleObject
16// that provides a notification callback, OnObjectSignaled, that runs back on
17// the origin thread (i.e., the thread that called StartWatching).
18//
19// This class acts like a smart pointer such that when it goes out-of-scope,
20// UnregisterWaitEx is automatically called, and any in-flight notification is
21// suppressed.
22//
23// Typical usage:
24//
25// class MyClass : public base::ObjectWatcher::Delegate {
26// public:
27// void DoStuffWhenSignaled(HANDLE object) {
28// watcher_.StartWatching(object, this);
29// }
30// virtual void OnObjectSignaled(HANDLE object) {
31// // OK, time to do stuff!
32// }
33// private:
34// base::ObjectWatcher watcher_;
35// };
36//
37// In the above example, MyClass wants to "do stuff" when object becomes
38// signaled. ObjectWatcher makes this task easy. When MyClass goes out of
39// scope, the watcher_ will be destroyed, and there is no need to worry about
40// OnObjectSignaled being called on a deleted MyClass pointer. Easy!
41//
darin@google.com965e5342008-08-06 08:16:41 +090042class ObjectWatcher : public MessageLoop::DestructionObserver {
darin@google.com6a4581b2008-08-02 06:04:03 +090043 public:
darin@google.com18f923a2008-08-05 02:46:47 +090044 class Delegate {
45 public:
46 virtual ~Delegate() {}
47 // Called from the MessageLoop when a signaled object is detected. To
48 // continue watching the object, AddWatch must be called again.
49 virtual void OnObjectSignaled(HANDLE object) = 0;
50 };
51
darin@google.com6a4581b2008-08-02 06:04:03 +090052 ObjectWatcher();
53 ~ObjectWatcher();
54
darin@google.com18f923a2008-08-05 02:46:47 +090055 // When the object is signaled, the given delegate is notified on the thread
56 // where StartWatching is called. The ObjectWatcher is not responsible for
57 // deleting the delegate.
darin@google.com6a4581b2008-08-02 06:04:03 +090058 //
darin@google.com18f923a2008-08-05 02:46:47 +090059 // Returns true if the watch was started. Otherwise, false is returned.
darin@google.com6a4581b2008-08-02 06:04:03 +090060 //
darin@google.com18f923a2008-08-05 02:46:47 +090061 bool StartWatching(HANDLE object, Delegate* delegate);
darin@google.com6a4581b2008-08-02 06:04:03 +090062
darin@google.com18f923a2008-08-05 02:46:47 +090063 // Stops watching. Does nothing if the watch has already completed. If the
64 // watch is still active, then it is canceled, and the associated delegate is
65 // not notified.
darin@google.com6a4581b2008-08-02 06:04:03 +090066 //
67 // Returns true if the watch was canceled. Otherwise, false is returned.
68 //
darin@google.com18f923a2008-08-05 02:46:47 +090069 bool StopWatching();
darin@google.com6a4581b2008-08-02 06:04:03 +090070
71 private:
72 // Called on a background thread when done waiting.
73 static void CALLBACK DoneWaiting(void* param, BOOLEAN timed_out);
74
darin@google.com965e5342008-08-06 08:16:41 +090075 // MessageLoop::DestructionObserver implementation:
76 virtual void WillDestroyCurrentMessageLoop();
77
darin@google.com18f923a2008-08-05 02:46:47 +090078 // Internal state.
darin@google.com6a4581b2008-08-02 06:04:03 +090079 struct Watch;
darin@google.com18f923a2008-08-05 02:46:47 +090080 Watch* watch_;
darin@google.com6a4581b2008-08-02 06:04:03 +090081
darin@google.com18f923a2008-08-05 02:46:47 +090082 DISALLOW_COPY_AND_ASSIGN(ObjectWatcher);
83};
darin@google.com6a4581b2008-08-02 06:04:03 +090084} // namespace base
85
86#endif // BASE_OBJECT_WATCHER_H_
license.botf003cfe2008-08-24 09:55:55 +090087