diff options
Diffstat (limited to 'base/synchronization/waitable_event_watcher.h')
-rw-r--r-- | base/synchronization/waitable_event_watcher.h | 92 |
1 files changed, 71 insertions, 21 deletions
diff --git a/base/synchronization/waitable_event_watcher.h b/base/synchronization/waitable_event_watcher.h index fe61f96..f5c1510 100644 --- a/base/synchronization/waitable_event_watcher.h +++ b/base/synchronization/waitable_event_watcher.h @@ -23,6 +23,7 @@ class AsyncWaiter; class AsyncCallbackTask; class WaitableEvent; +// ----------------------------------------------------------------------------- // This class provides a way to wait on a WaitableEvent asynchronously. // // Each instance of this object can be waiting on a single WaitableEvent. When @@ -31,13 +32,12 @@ class WaitableEvent; // // Typical usage: // -// class MyClass { +// class MyClass : public base::WaitableEventWatcher::Delegate { // public: // void DoStuffWhenSignaled(WaitableEvent *waitable_event) { -// watcher_.StartWatching(waitable_event, -// base::Bind(&MyClass::OnWaitableEventSignaled, this); +// watcher_.StartWatching(waitable_event, this); // } -// void OnWaitableEventSignaled(WaitableEvent* waitable_event) { +// virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) { // // OK, time to do stuff! // } // private: @@ -57,56 +57,106 @@ class WaitableEvent; // // NOTE: you /are/ allowed to delete the WaitableEvent while still waiting on // it with a Watcher. It will act as if the event was never signaled. +// ----------------------------------------------------------------------------- class BASE_EXPORT WaitableEventWatcher -#if defined(OS_WIN) - : public win::ObjectWatcher::Delegate { -#else - : public MessageLoop::DestructionObserver { +#if !defined(OS_WIN) + : public MessageLoop::DestructionObserver #endif +{ public: - typedef Callback<void(WaitableEvent*)> EventCallback; + WaitableEventWatcher(); virtual ~WaitableEventWatcher(); - // When @event is signaled, the given callback is called on the thread of the - // current message loop when StartWatching is called. - bool StartWatching(WaitableEvent* event, const EventCallback& callback); - + class BASE_EXPORT Delegate { + public: + // ------------------------------------------------------------------------- + // This is called on the MessageLoop thread when WaitableEvent has been + // signaled. + // + // Note: the event may not be signaled by the time that this function is + // called. This indicates only that it has been signaled at some point in + // the past. + // ------------------------------------------------------------------------- + virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) = 0; + + protected: + virtual ~Delegate() { } + }; + + // --------------------------------------------------------------------------- + // When @event is signaled, the given delegate is called on the thread of the + // current message loop when StartWatching is called. The delegate is not + // deleted. + // --------------------------------------------------------------------------- + bool StartWatching(WaitableEvent* event, Delegate* delegate); + + // --------------------------------------------------------------------------- // Cancel the current watch. Must be called from the same thread which // started the watch. // // Does nothing if no event is being watched, nor if the watch has completed. - // The callback will *not* be called for the current watch after this - // function returns. Since the callback runs on the same thread as this + // The delegate will *not* be called for the current watch after this + // function returns. Since the delegate runs on the same thread as this // function, it cannot be called during this function either. + // --------------------------------------------------------------------------- void StopWatching(); + // --------------------------------------------------------------------------- // Return the currently watched event, or NULL if no object is currently being // watched. + // --------------------------------------------------------------------------- WaitableEvent* GetWatchedEvent(); - // Return the callback that will be invoked when the event is - // signaled. - const EventCallback& callback() const { return callback_; } + // --------------------------------------------------------------------------- + // Return the delegate, or NULL if there is no delegate. + // --------------------------------------------------------------------------- + Delegate* delegate() { + return delegate_; + } private: #if defined(OS_WIN) - virtual void OnObjectSignaled(HANDLE h) OVERRIDE; + // --------------------------------------------------------------------------- + // The helper class exists because, if WaitableEventWatcher were to inherit + // from ObjectWatcher::Delegate, then it couldn't also have an inner class + // called Delegate (at least on Windows). Thus this object exists to proxy + // the callback function + // --------------------------------------------------------------------------- + class ObjectWatcherHelper : public win::ObjectWatcher::Delegate { + public: + ObjectWatcherHelper(WaitableEventWatcher* watcher); + + // ------------------------------------------------------------------------- + // Implementation of ObjectWatcher::Delegate + // ------------------------------------------------------------------------- + void OnObjectSignaled(HANDLE h); + + private: + WaitableEventWatcher *const watcher_; + }; + + void OnObjectSignaled(); + + ObjectWatcherHelper helper_; win::ObjectWatcher watcher_; #else + // --------------------------------------------------------------------------- // Implementation of MessageLoop::DestructionObserver + // --------------------------------------------------------------------------- virtual void WillDestroyCurrentMessageLoop() OVERRIDE; MessageLoop* message_loop_; scoped_refptr<Flag> cancel_flag_; AsyncWaiter* waiter_; - base::Closure internal_callback_; + base::Closure callback_; scoped_refptr<WaitableEvent::WaitableEventKernel> kernel_; #endif WaitableEvent* event_; - EventCallback callback_; + + Delegate* delegate_; }; } // namespace base |