Home | History | Annotate | Download | only in base
      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_WAITABLE_EVENT_WATCHER_H_
      6 #define BASE_WAITABLE_EVENT_WATCHER_H_
      7 
      8 #include "build/build_config.h"
      9 
     10 #if defined(OS_WIN)
     11 #include "base/object_watcher.h"
     12 #else
     13 #include "base/message_loop.h"
     14 #include "base/waitable_event.h"
     15 #endif
     16 
     17 namespace base {
     18 
     19 class Flag;
     20 class AsyncWaiter;
     21 class AsyncCallbackTask;
     22 class WaitableEvent;
     23 
     24 // -----------------------------------------------------------------------------
     25 // This class provides a way to wait on a WaitableEvent asynchronously.
     26 //
     27 // Each instance of this object can be waiting on a single WaitableEvent. When
     28 // the waitable event is signaled, a callback is made in the thread of a given
     29 // MessageLoop. This callback can be deleted by deleting the waiter.
     30 //
     31 // Typical usage:
     32 //
     33 //   class MyClass : public base::WaitableEventWatcher::Delegate {
     34 //    public:
     35 //     void DoStuffWhenSignaled(WaitableEvent *waitable_event) {
     36 //       watcher_.StartWatching(waitable_event, this);
     37 //     }
     38 //     virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) {
     39 //       // OK, time to do stuff!
     40 //     }
     41 //    private:
     42 //     base::WaitableEventWatcher watcher_;
     43 //   };
     44 //
     45 // In the above example, MyClass wants to "do stuff" when waitable_event
     46 // becomes signaled. WaitableEventWatcher makes this task easy. When MyClass
     47 // goes out of scope, the watcher_ will be destroyed, and there is no need to
     48 // worry about OnWaitableEventSignaled being called on a deleted MyClass
     49 // pointer.
     50 //
     51 // BEWARE: With automatically reset WaitableEvents, a signal may be lost if it
     52 // occurs just before a WaitableEventWatcher is deleted. There is currently no
     53 // safe way to stop watching an automatic reset WaitableEvent without possibly
     54 // missing a signal.
     55 //
     56 // NOTE: you /are/ allowed to delete the WaitableEvent while still waiting on
     57 // it with a Watcher. It will act as if the event was never signaled.
     58 // -----------------------------------------------------------------------------
     59 
     60 class WaitableEventWatcher
     61 #if defined(OS_POSIX)
     62     : public MessageLoop::DestructionObserver
     63 #endif
     64 {
     65  public:
     66 
     67   WaitableEventWatcher();
     68   ~WaitableEventWatcher();
     69 
     70   class Delegate {
     71    public:
     72     virtual ~Delegate() { }
     73 
     74     // -------------------------------------------------------------------------
     75     // This is called on the MessageLoop thread when WaitableEvent has been
     76     // signaled.
     77     //
     78     // Note: the event may not be signaled by the time that this function is
     79     // called. This indicates only that it has been signaled at some point in
     80     // the past.
     81     // -------------------------------------------------------------------------
     82     virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) = 0;
     83   };
     84 
     85   // ---------------------------------------------------------------------------
     86   // When @event is signaled, the given delegate is called on the thread of the
     87   // current message loop when StartWatching is called. The delegate is not
     88   // deleted.
     89   // ---------------------------------------------------------------------------
     90   bool StartWatching(WaitableEvent* event, Delegate* delegate);
     91 
     92   // ---------------------------------------------------------------------------
     93   // Cancel the current watch. Must be called from the same thread which
     94   // started the watch.
     95   //
     96   // Does nothing if no event is being watched, nor if the watch has completed.
     97   // The delegate will *not* be called for the current watch after this
     98   // function returns. Since the delegate runs on the same thread as this
     99   // function, it cannot be called during this function either.
    100   // ---------------------------------------------------------------------------
    101   void StopWatching();
    102 
    103   // ---------------------------------------------------------------------------
    104   // Return the currently watched event, or NULL if no object is currently being
    105   // watched.
    106   // ---------------------------------------------------------------------------
    107   WaitableEvent* GetWatchedEvent();
    108 
    109   // ---------------------------------------------------------------------------
    110   // Return the delegate, or NULL if there is no delegate.
    111   // ---------------------------------------------------------------------------
    112   Delegate* delegate() {
    113     return delegate_;
    114   }
    115 
    116  private:
    117   WaitableEvent* event_;
    118 
    119 #if defined(OS_WIN)
    120   // ---------------------------------------------------------------------------
    121   // The helper class exists because, if WaitableEventWatcher were to inherit
    122   // from ObjectWatcher::Delegate, then it couldn't also have an inner class
    123   // called Delegate (at least on Windows). Thus this object exists to proxy
    124   // the callback function
    125   // ---------------------------------------------------------------------------
    126   class ObjectWatcherHelper : public ObjectWatcher::Delegate {
    127    public:
    128     ObjectWatcherHelper(WaitableEventWatcher* watcher);
    129 
    130     // -------------------------------------------------------------------------
    131     // Implementation of ObjectWatcher::Delegate
    132     // -------------------------------------------------------------------------
    133     void OnObjectSignaled(HANDLE h);
    134 
    135    private:
    136     WaitableEventWatcher *const watcher_;
    137   };
    138 
    139   void OnObjectSignaled();
    140 
    141   ObjectWatcherHelper helper_;
    142   ObjectWatcher watcher_;
    143 #else
    144   // ---------------------------------------------------------------------------
    145   // Implementation of MessageLoop::DestructionObserver
    146   // ---------------------------------------------------------------------------
    147   void WillDestroyCurrentMessageLoop();
    148 
    149   MessageLoop* message_loop_;
    150   scoped_refptr<Flag> cancel_flag_;
    151   AsyncWaiter* waiter_;
    152   AsyncCallbackTask* callback_task_;
    153   scoped_refptr<WaitableEvent::WaitableEventKernel> kernel_;
    154 #endif
    155 
    156   Delegate* delegate_;
    157 };
    158 
    159 }  // namespace base
    160 
    161 #endif  // BASE_WAITABLE_EVENT_WATCHER_H_
    162