Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2014 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #ifndef WEBRTC_BASE_ASYNCINVOKER_H_
     12 #define WEBRTC_BASE_ASYNCINVOKER_H_
     13 
     14 #include "webrtc/base/asyncinvoker-inl.h"
     15 #include "webrtc/base/bind.h"
     16 #include "webrtc/base/sigslot.h"
     17 #include "webrtc/base/scopedptrcollection.h"
     18 #include "webrtc/base/thread.h"
     19 
     20 namespace rtc {
     21 
     22 // Invokes function objects (aka functors) asynchronously on a Thread, and
     23 // owns the lifetime of calls (ie, when this object is destroyed, calls in
     24 // flight are cancelled). AsyncInvoker can optionally execute a user-specified
     25 // function when the asynchronous call is complete, or operates in
     26 // fire-and-forget mode otherwise.
     27 //
     28 // AsyncInvoker does not own the thread it calls functors on.
     29 //
     30 // A note about async calls and object lifetimes: users should
     31 // be mindful of object lifetimes when calling functions asynchronously and
     32 // ensure objects used by the function _cannot_ be deleted between the
     33 // invocation and execution of the functor. AsyncInvoker is designed to
     34 // help: any calls in flight will be cancelled when the AsyncInvoker used to
     35 // make the call is destructed, and any calls executing will be allowed to
     36 // complete before AsyncInvoker destructs.
     37 //
     38 // The easiest way to ensure lifetimes are handled correctly is to create a
     39 // class that owns the Thread and AsyncInvoker objects, and then call its
     40 // methods asynchronously as needed.
     41 //
     42 // Example:
     43 //   class MyClass {
     44 //    public:
     45 //     void FireAsyncTaskWithResult(Thread* thread, int x) {
     46 //       // Specify a callback to get the result upon completion.
     47 //       invoker_.AsyncInvoke<int>(
     48 //           thread, Bind(&MyClass::AsyncTaskWithResult, this, x),
     49 //           &MyClass::OnTaskComplete, this);
     50 //     }
     51 //     void FireAnotherAsyncTask(Thread* thread) {
     52 //       // No callback specified means fire-and-forget.
     53 //       invoker_.AsyncInvoke<void>(
     54 //           thread, Bind(&MyClass::AnotherAsyncTask, this));
     55 //
     56 //    private:
     57 //     int AsyncTaskWithResult(int x) {
     58 //       // Some long running process...
     59 //       return x * x;
     60 //     }
     61 //     void AnotherAsyncTask() {
     62 //       // Some other long running process...
     63 //     }
     64 //     void OnTaskComplete(int result) { result_ = result; }
     65 //
     66 //     AsyncInvoker invoker_;
     67 //     int result_;
     68 //   };
     69 class AsyncInvoker : public MessageHandler {
     70  public:
     71   AsyncInvoker();
     72   virtual ~AsyncInvoker();
     73 
     74   // Call |functor| asynchronously on |thread|, with no callback upon
     75   // completion. Returns immediately.
     76   template <class ReturnT, class FunctorT>
     77   void AsyncInvoke(Thread* thread,
     78                    const FunctorT& functor,
     79                    uint32 id = 0) {
     80     AsyncClosure* closure =
     81         new RefCountedObject<FireAndForgetAsyncClosure<FunctorT> >(functor);
     82     DoInvoke(thread, closure, id);
     83   }
     84 
     85   // Call |functor| asynchronously on |thread|, calling |callback| when done.
     86   template <class ReturnT, class FunctorT, class HostT>
     87   void AsyncInvoke(Thread* thread,
     88                    const FunctorT& functor,
     89                    void (HostT::*callback)(ReturnT),
     90                    HostT* callback_host,
     91                    uint32 id = 0) {
     92     AsyncClosure* closure =
     93         new RefCountedObject<NotifyingAsyncClosure<ReturnT, FunctorT, HostT> >(
     94             this, Thread::Current(), functor, callback, callback_host);
     95     DoInvoke(thread, closure, id);
     96   }
     97 
     98   // Call |functor| asynchronously on |thread|, calling |callback| when done.
     99   // Overloaded for void return.
    100   template <class ReturnT, class FunctorT, class HostT>
    101   void AsyncInvoke(Thread* thread,
    102                    const FunctorT& functor,
    103                    void (HostT::*callback)(),
    104                    HostT* callback_host,
    105                    uint32 id = 0) {
    106     AsyncClosure* closure =
    107         new RefCountedObject<NotifyingAsyncClosure<void, FunctorT, HostT> >(
    108             this, Thread::Current(), functor, callback, callback_host);
    109     DoInvoke(thread, closure, id);
    110   }
    111 
    112   // Synchronously execute on |thread| all outstanding calls we own
    113   // that are pending on |thread|, and wait for calls to complete
    114   // before returning. Optionally filter by message id.
    115   // The destructor will not wait for outstanding calls, so if that
    116   // behavior is desired, call Flush() before destroying this object.
    117   void Flush(Thread* thread, uint32 id = MQID_ANY);
    118 
    119   // Signaled when this object is destructed.
    120   sigslot::signal0<> SignalInvokerDestroyed;
    121 
    122  private:
    123   virtual void OnMessage(Message* msg);
    124   void DoInvoke(Thread* thread, AsyncClosure* closure, uint32 id);
    125 
    126   bool destroying_;
    127 
    128   DISALLOW_COPY_AND_ASSIGN(AsyncInvoker);
    129 };
    130 
    131 }  // namespace rtc
    132 
    133 
    134 #endif  // WEBRTC_BASE_ASYNCINVOKER_H_
    135