|
1 // 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. |
|
4 |
|
5 #ifndef BASE_OBJECT_WATCHER_H_ |
|
6 #define BASE_OBJECT_WATCHER_H_ |
|
7 |
|
8 #include <windows.h> |
|
9 #ifdef GetClassName |
|
10 #undef GetClassName |
|
11 #endif |
|
12 |
|
13 #include "base/message_loop.h" |
|
14 |
|
15 namespace base { |
|
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 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 base |
|
93 |
|
94 #endif // BASE_OBJECT_WATCHER_H_ |