summaryrefslogtreecommitdiffstats
path: root/base/synchronization/waitable_event_watcher.h
diff options
context:
space:
mode:
Diffstat (limited to 'base/synchronization/waitable_event_watcher.h')
-rw-r--r--base/synchronization/waitable_event_watcher.h92
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