• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #include <windows.h>
9 
10 #include "base/base_export.h"
11 #include "base/callback.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 
15 namespace base {
16 namespace win {
17 
18 // A class that provides a means to asynchronously wait for a Windows object to
19 // become signaled.  It is an abstraction around RegisterWaitForSingleObject
20 // that provides a notification callback, OnObjectSignaled, that runs back on
21 // the origin thread (i.e., the thread that called StartWatching).
22 //
23 // This class acts like a smart pointer such that when it goes out-of-scope,
24 // UnregisterWaitEx is automatically called, and any in-flight notification is
25 // suppressed.
26 //
27 // Typical usage:
28 //
29 //   class MyClass : public base::ObjectWatcher::Delegate {
30 //    public:
31 //     void DoStuffWhenSignaled(HANDLE object) {
32 //       watcher_.StartWatching(object, this);
33 //     }
34 //     virtual void OnObjectSignaled(HANDLE object) {
35 //       // OK, time to do stuff!
36 //     }
37 //    private:
38 //     base::ObjectWatcher watcher_;
39 //   };
40 //
41 // In the above example, MyClass wants to "do stuff" when object becomes
42 // signaled.  ObjectWatcher makes this task easy.  When MyClass goes out of
43 // scope, the watcher_ will be destroyed, and there is no need to worry about
44 // OnObjectSignaled being called on a deleted MyClass pointer.  Easy!
45 // If the object is already signaled before being watched, OnObjectSignaled is
46 // still called after (but not necessarily immediately after) watch is started.
47 //
48 class BASE_EXPORT ObjectWatcher : public MessageLoop::DestructionObserver {
49  public:
50   class BASE_EXPORT Delegate {
51    public:
~Delegate()52     virtual ~Delegate() {}
53     // Called from the MessageLoop when a signaled object is detected.  To
54     // continue watching the object, StartWatching must be called again.
55     virtual void OnObjectSignaled(HANDLE object) = 0;
56   };
57 
58   ObjectWatcher();
59   ~ObjectWatcher();
60 
61   // When the object is signaled, the given delegate is notified on the thread
62   // where StartWatching is called.  The ObjectWatcher is not responsible for
63   // deleting the delegate.
64   //
65   // Returns true if the watch was started.  Otherwise, false is returned.
66   //
67   bool StartWatching(HANDLE object, Delegate* delegate);
68 
69   // Stops watching.  Does nothing if the watch has already completed.  If the
70   // watch is still active, then it is canceled, and the associated delegate is
71   // not notified.
72   //
73   // Returns true if the watch was canceled.  Otherwise, false is returned.
74   //
75   bool StopWatching();
76 
77   // Returns the handle of the object being watched, or NULL if the object
78   // watcher is stopped.
79   HANDLE GetWatchedObject();
80 
81  private:
82   // Called on a background thread when done waiting.
83   static void CALLBACK DoneWaiting(void* param, BOOLEAN timed_out);
84 
85   void Signal(Delegate* delegate);
86 
87   // MessageLoop::DestructionObserver implementation:
88   virtual void WillDestroyCurrentMessageLoop();
89 
90   // Internal state.
91   Closure callback_;
92   HANDLE object_;             // The object being watched
93   HANDLE wait_object_;        // Returned by RegisterWaitForSingleObject
94   MessageLoop* origin_loop_;  // Used to get back to the origin thread
95 
96   WeakPtrFactory<ObjectWatcher> weak_factory_;
97 
98   DISALLOW_COPY_AND_ASSIGN(ObjectWatcher);
99 };
100 
101 }  // namespace win
102 }  // namespace base
103 
104 #endif  // BASE_OBJECT_WATCHER_H_
105