1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/waitable_event_watcher.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,153 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef BASE_WAITABLE_EVENT_WATCHER_H_ 1.9 +#define BASE_WAITABLE_EVENT_WATCHER_H_ 1.10 + 1.11 +#include "build/build_config.h" 1.12 + 1.13 +#if defined(OS_WIN) 1.14 +#include "base/object_watcher.h" 1.15 +#else 1.16 +#include "base/message_loop.h" 1.17 +#include "base/waitable_event.h" 1.18 +#endif 1.19 + 1.20 +namespace base { 1.21 + 1.22 +class Flag; 1.23 +class AsyncWaiter; 1.24 +class AsyncCallbackTask; 1.25 +class WaitableEvent; 1.26 + 1.27 +// ----------------------------------------------------------------------------- 1.28 +// This class provides a way to wait on a WaitableEvent asynchronously. 1.29 +// 1.30 +// Each instance of this object can be waiting on a single WaitableEvent. When 1.31 +// the waitable event is signaled, a callback is made in the thread of a given 1.32 +// MessageLoop. This callback can be deleted by deleting the waiter. 1.33 +// 1.34 +// Typical usage: 1.35 +// 1.36 +// class MyClass : public base::WaitableEventWatcher::Delegate { 1.37 +// public: 1.38 +// void DoStuffWhenSignaled(WaitableEvent *waitable_event) { 1.39 +// watcher_.StartWatching(waitable_event, this); 1.40 +// } 1.41 +// virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) { 1.42 +// // OK, time to do stuff! 1.43 +// } 1.44 +// private: 1.45 +// base::WaitableEventWatcher watcher_; 1.46 +// }; 1.47 +// 1.48 +// In the above example, MyClass wants to "do stuff" when waitable_event 1.49 +// becomes signaled. WaitableEventWatcher makes this task easy. When MyClass 1.50 +// goes out of scope, the watcher_ will be destroyed, and there is no need to 1.51 +// worry about OnWaitableEventSignaled being called on a deleted MyClass 1.52 +// pointer. 1.53 +// 1.54 +// BEWARE: With automatically reset WaitableEvents, a signal may be lost if it 1.55 +// occurs just before a WaitableEventWatcher is deleted. There is currently no 1.56 +// safe way to stop watching an automatic reset WaitableEvent without possibly 1.57 +// missing a signal. 1.58 +// 1.59 +// NOTE: you /are/ allowed to delete the WaitableEvent while still waiting on 1.60 +// it with a Watcher. It will act as if the event was never signaled. 1.61 +// ----------------------------------------------------------------------------- 1.62 + 1.63 +class WaitableEventWatcher 1.64 +#if defined(OS_POSIX) 1.65 + : public MessageLoop::DestructionObserver 1.66 +#endif 1.67 +{ 1.68 + public: 1.69 + 1.70 + WaitableEventWatcher(); 1.71 + ~WaitableEventWatcher(); 1.72 + 1.73 + class Delegate { 1.74 + public: 1.75 + virtual ~Delegate() { } 1.76 + 1.77 + // ------------------------------------------------------------------------- 1.78 + // This is called on the MessageLoop thread when WaitableEvent has been 1.79 + // signaled. 1.80 + // 1.81 + // Note: the event may not be signaled by the time that this function is 1.82 + // called. This indicates only that it has been signaled at some point in 1.83 + // the past. 1.84 + // ------------------------------------------------------------------------- 1.85 + virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) = 0; 1.86 + }; 1.87 + 1.88 + // --------------------------------------------------------------------------- 1.89 + // When @event is signaled, the given delegate is called on the thread of the 1.90 + // current message loop when StartWatching is called. The delegate is not 1.91 + // deleted. 1.92 + // --------------------------------------------------------------------------- 1.93 + bool StartWatching(WaitableEvent* event, Delegate* delegate); 1.94 + 1.95 + // --------------------------------------------------------------------------- 1.96 + // Cancel the current watch. Must be called from the same thread which 1.97 + // started the watch. 1.98 + // 1.99 + // Does nothing if no event is being watched, nor if the watch has completed. 1.100 + // The delegate will *not* be called for the current watch after this 1.101 + // function returns. Since the delegate runs on the same thread as this 1.102 + // function, it cannot be called during this function either. 1.103 + // --------------------------------------------------------------------------- 1.104 + void StopWatching(); 1.105 + 1.106 + // --------------------------------------------------------------------------- 1.107 + // Return the currently watched event, or NULL if no object is currently being 1.108 + // watched. 1.109 + // --------------------------------------------------------------------------- 1.110 + WaitableEvent* GetWatchedEvent(); 1.111 + 1.112 + private: 1.113 + WaitableEvent* event_; 1.114 + 1.115 +#if defined(OS_WIN) 1.116 + // --------------------------------------------------------------------------- 1.117 + // The helper class exists because, if WaitableEventWatcher were to inherit 1.118 + // from ObjectWatcher::Delegate, then it couldn't also have an inner class 1.119 + // called Delegate (at least on Windows). Thus this object exists to proxy 1.120 + // the callback function 1.121 + // --------------------------------------------------------------------------- 1.122 + class ObjectWatcherHelper : public ObjectWatcher::Delegate { 1.123 + public: 1.124 + ObjectWatcherHelper(WaitableEventWatcher* watcher); 1.125 + 1.126 + // ------------------------------------------------------------------------- 1.127 + // Implementation of ObjectWatcher::Delegate 1.128 + // ------------------------------------------------------------------------- 1.129 + void OnObjectSignaled(HANDLE h); 1.130 + 1.131 + private: 1.132 + WaitableEventWatcher *const watcher_; 1.133 + }; 1.134 + 1.135 + void OnObjectSignaled(); 1.136 + 1.137 + Delegate* delegate_; 1.138 + ObjectWatcherHelper helper_; 1.139 + ObjectWatcher watcher_; 1.140 +#else 1.141 + // --------------------------------------------------------------------------- 1.142 + // Implementation of MessageLoop::DestructionObserver 1.143 + // --------------------------------------------------------------------------- 1.144 + void WillDestroyCurrentMessageLoop(); 1.145 + 1.146 + MessageLoop* message_loop_; 1.147 + scoped_refptr<Flag> cancel_flag_; 1.148 + AsyncWaiter* waiter_; 1.149 + AsyncCallbackTask* callback_task_; 1.150 + scoped_refptr<WaitableEvent::WaitableEventKernel> kernel_; 1.151 +#endif 1.152 +}; 1.153 + 1.154 +} // namespace base 1.155 + 1.156 +#endif // BASE_WAITABLE_EVENT_WATCHER_H_