| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  *  Copyright 2014 The WebRTC Project Authors. All rights reserved. | 2  *  Copyright 2014 The WebRTC Project Authors. All rights reserved. | 
| 3  * | 3  * | 
| 4  *  Use of this source code is governed by a BSD-style license | 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 | 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 | 6  *  tree. An additional intellectual property rights grant can be found | 
| 7  *  in the file PATENTS.  All contributing project authors may | 7  *  in the file PATENTS.  All contributing project authors may | 
| 8  *  be found in the AUTHORS file in the root of the source tree. | 8  *  be found in the AUTHORS file in the root of the source tree. | 
| 9  */ | 9  */ | 
| 10 | 10 | 
| 11 #ifndef WEBRTC_BASE_ASYNCINVOKER_H_ | 11 #ifndef WEBRTC_BASE_ASYNCINVOKER_H_ | 
| 12 #define WEBRTC_BASE_ASYNCINVOKER_H_ | 12 #define WEBRTC_BASE_ASYNCINVOKER_H_ | 
| 13 | 13 | 
| 14 #include <memory> |  | 
| 15 #include <utility> |  | 
| 16 | 14 | 
| 17 #include "webrtc/base/asyncinvoker-inl.h" | 15 // This header is deprecated and is just left here temporarily during | 
| 18 #include "webrtc/base/bind.h" | 16 // refactoring. See https://bugs.webrtc.org/7634 for more details. | 
| 19 #include "webrtc/base/constructormagic.h" | 17 #include "webrtc/rtc_base/asyncinvoker.h" | 
| 20 #include "webrtc/base/event.h" |  | 
| 21 #include "webrtc/base/sigslot.h" |  | 
| 22 #include "webrtc/base/thread.h" |  | 
| 23 |  | 
| 24 namespace rtc { |  | 
| 25 |  | 
| 26 // Invokes function objects (aka functors) asynchronously on a Thread, and |  | 
| 27 // owns the lifetime of calls (ie, when this object is destroyed, calls in |  | 
| 28 // flight are cancelled). AsyncInvoker can optionally execute a user-specified |  | 
| 29 // function when the asynchronous call is complete, or operates in |  | 
| 30 // fire-and-forget mode otherwise. |  | 
| 31 // |  | 
| 32 // AsyncInvoker does not own the thread it calls functors on. |  | 
| 33 // |  | 
| 34 // A note about async calls and object lifetimes: users should |  | 
| 35 // be mindful of object lifetimes when calling functions asynchronously and |  | 
| 36 // ensure objects used by the function _cannot_ be deleted between the |  | 
| 37 // invocation and execution of the functor. AsyncInvoker is designed to |  | 
| 38 // help: any calls in flight will be cancelled when the AsyncInvoker used to |  | 
| 39 // make the call is destructed, and any calls executing will be allowed to |  | 
| 40 // complete before AsyncInvoker destructs. |  | 
| 41 // |  | 
| 42 // The easiest way to ensure lifetimes are handled correctly is to create a |  | 
| 43 // class that owns the Thread and AsyncInvoker objects, and then call its |  | 
| 44 // methods asynchronously as needed. |  | 
| 45 // |  | 
| 46 // Example: |  | 
| 47 //   class MyClass { |  | 
| 48 //    public: |  | 
| 49 //     void FireAsyncTaskWithResult(Thread* thread, int x) { |  | 
| 50 //       // Specify a callback to get the result upon completion. |  | 
| 51 //       invoker_.AsyncInvoke<int>(RTC_FROM_HERE, |  | 
| 52 //           thread, Bind(&MyClass::AsyncTaskWithResult, this, x), |  | 
| 53 //           &MyClass::OnTaskComplete, this); |  | 
| 54 //     } |  | 
| 55 //     void FireAnotherAsyncTask(Thread* thread) { |  | 
| 56 //       // No callback specified means fire-and-forget. |  | 
| 57 //       invoker_.AsyncInvoke<void>(RTC_FROM_HERE, |  | 
| 58 //           thread, Bind(&MyClass::AnotherAsyncTask, this)); |  | 
| 59 // |  | 
| 60 //    private: |  | 
| 61 //     int AsyncTaskWithResult(int x) { |  | 
| 62 //       // Some long running process... |  | 
| 63 //       return x * x; |  | 
| 64 //     } |  | 
| 65 //     void AnotherAsyncTask() { |  | 
| 66 //       // Some other long running process... |  | 
| 67 //     } |  | 
| 68 //     void OnTaskComplete(int result) { result_ = result; } |  | 
| 69 // |  | 
| 70 //     AsyncInvoker invoker_; |  | 
| 71 //     int result_; |  | 
| 72 //   }; |  | 
| 73 class AsyncInvoker : public MessageHandler { |  | 
| 74  public: |  | 
| 75   AsyncInvoker(); |  | 
| 76   ~AsyncInvoker() override; |  | 
| 77 |  | 
| 78   // Call |functor| asynchronously on |thread|, with no callback upon |  | 
| 79   // completion. Returns immediately. |  | 
| 80   template <class ReturnT, class FunctorT> |  | 
| 81   void AsyncInvoke(const Location& posted_from, |  | 
| 82                    Thread* thread, |  | 
| 83                    const FunctorT& functor, |  | 
| 84                    uint32_t id = 0) { |  | 
| 85     std::unique_ptr<AsyncClosure> closure( |  | 
| 86         new FireAndForgetAsyncClosure<FunctorT>(this, functor)); |  | 
| 87     DoInvoke(posted_from, thread, std::move(closure), id); |  | 
| 88   } |  | 
| 89 |  | 
| 90   // Call |functor| asynchronously on |thread| with |delay_ms|, with no callback |  | 
| 91   // upon completion. Returns immediately. |  | 
| 92   template <class ReturnT, class FunctorT> |  | 
| 93   void AsyncInvokeDelayed(const Location& posted_from, |  | 
| 94                           Thread* thread, |  | 
| 95                           const FunctorT& functor, |  | 
| 96                           uint32_t delay_ms, |  | 
| 97                           uint32_t id = 0) { |  | 
| 98     std::unique_ptr<AsyncClosure> closure( |  | 
| 99         new FireAndForgetAsyncClosure<FunctorT>(this, functor)); |  | 
| 100     DoInvokeDelayed(posted_from, thread, std::move(closure), delay_ms, id); |  | 
| 101   } |  | 
| 102 |  | 
| 103   // Synchronously execute on |thread| all outstanding calls we own |  | 
| 104   // that are pending on |thread|, and wait for calls to complete |  | 
| 105   // before returning. Optionally filter by message id. |  | 
| 106   // The destructor will not wait for outstanding calls, so if that |  | 
| 107   // behavior is desired, call Flush() before destroying this object. |  | 
| 108   void Flush(Thread* thread, uint32_t id = MQID_ANY); |  | 
| 109 |  | 
| 110  private: |  | 
| 111   void OnMessage(Message* msg) override; |  | 
| 112   void DoInvoke(const Location& posted_from, |  | 
| 113                 Thread* thread, |  | 
| 114                 std::unique_ptr<AsyncClosure> closure, |  | 
| 115                 uint32_t id); |  | 
| 116   void DoInvokeDelayed(const Location& posted_from, |  | 
| 117                        Thread* thread, |  | 
| 118                        std::unique_ptr<AsyncClosure> closure, |  | 
| 119                        uint32_t delay_ms, |  | 
| 120                        uint32_t id); |  | 
| 121   volatile int pending_invocations_ = 0; |  | 
| 122   Event invocation_complete_; |  | 
| 123   bool destroying_ = false; |  | 
| 124   friend class AsyncClosure; |  | 
| 125 |  | 
| 126   RTC_DISALLOW_COPY_AND_ASSIGN(AsyncInvoker); |  | 
| 127 }; |  | 
| 128 |  | 
| 129 // Similar to AsyncInvoker, but guards against the Thread being destroyed while |  | 
| 130 // there are outstanding dangling pointers to it. It will connect to the current |  | 
| 131 // thread in the constructor, and will get notified when that thread is |  | 
| 132 // destroyed. After GuardedAsyncInvoker is constructed, it can be used from |  | 
| 133 // other threads to post functors to the thread it was constructed on. If that |  | 
| 134 // thread dies, any further calls to AsyncInvoke() will be safely ignored. |  | 
| 135 class GuardedAsyncInvoker : public sigslot::has_slots<> { |  | 
| 136  public: |  | 
| 137   GuardedAsyncInvoker(); |  | 
| 138   ~GuardedAsyncInvoker() override; |  | 
| 139 |  | 
| 140   // Synchronously execute all outstanding calls we own, and wait for calls to |  | 
| 141   // complete before returning. Optionally filter by message id. The destructor |  | 
| 142   // will not wait for outstanding calls, so if that behavior is desired, call |  | 
| 143   // Flush() first. Returns false if the thread has died. |  | 
| 144   bool Flush(uint32_t id = MQID_ANY); |  | 
| 145 |  | 
| 146   // Call |functor| asynchronously with no callback upon completion. Returns |  | 
| 147   // immediately. Returns false if the thread has died. |  | 
| 148   template <class ReturnT, class FunctorT> |  | 
| 149   bool AsyncInvoke(const Location& posted_from, |  | 
| 150                    const FunctorT& functor, |  | 
| 151                    uint32_t id = 0) { |  | 
| 152     rtc::CritScope cs(&crit_); |  | 
| 153     if (thread_ == nullptr) |  | 
| 154       return false; |  | 
| 155     invoker_.AsyncInvoke<ReturnT, FunctorT>(posted_from, thread_, functor, id); |  | 
| 156     return true; |  | 
| 157   } |  | 
| 158 |  | 
| 159   // Call |functor| asynchronously with |delay_ms|, with no callback upon |  | 
| 160   // completion. Returns immediately. Returns false if the thread has died. |  | 
| 161   template <class ReturnT, class FunctorT> |  | 
| 162   bool AsyncInvokeDelayed(const Location& posted_from, |  | 
| 163                           const FunctorT& functor, |  | 
| 164                           uint32_t delay_ms, |  | 
| 165                           uint32_t id = 0) { |  | 
| 166     rtc::CritScope cs(&crit_); |  | 
| 167     if (thread_ == nullptr) |  | 
| 168       return false; |  | 
| 169     invoker_.AsyncInvokeDelayed<ReturnT, FunctorT>(posted_from, thread_, |  | 
| 170                                                    functor, delay_ms, id); |  | 
| 171     return true; |  | 
| 172   } |  | 
| 173 |  | 
| 174   // Call |functor| asynchronously, calling |callback| when done. Returns false |  | 
| 175   // if the thread has died. |  | 
| 176   template <class ReturnT, class FunctorT, class HostT> |  | 
| 177   bool AsyncInvoke(const Location& posted_from, |  | 
| 178                    const Location& callback_posted_from, |  | 
| 179                    const FunctorT& functor, |  | 
| 180                    void (HostT::*callback)(ReturnT), |  | 
| 181                    HostT* callback_host, |  | 
| 182                    uint32_t id = 0) { |  | 
| 183     rtc::CritScope cs(&crit_); |  | 
| 184     if (thread_ == nullptr) |  | 
| 185       return false; |  | 
| 186     invoker_.AsyncInvoke<ReturnT, FunctorT, HostT>( |  | 
| 187         posted_from, callback_posted_from, thread_, functor, callback, |  | 
| 188         callback_host, id); |  | 
| 189     return true; |  | 
| 190   } |  | 
| 191 |  | 
| 192   // Call |functor| asynchronously calling |callback| when done. Overloaded for |  | 
| 193   // void return. Returns false if the thread has died. |  | 
| 194   template <class ReturnT, class FunctorT, class HostT> |  | 
| 195   bool AsyncInvoke(const Location& posted_from, |  | 
| 196                    const Location& callback_posted_from, |  | 
| 197                    const FunctorT& functor, |  | 
| 198                    void (HostT::*callback)(), |  | 
| 199                    HostT* callback_host, |  | 
| 200                    uint32_t id = 0) { |  | 
| 201     rtc::CritScope cs(&crit_); |  | 
| 202     if (thread_ == nullptr) |  | 
| 203       return false; |  | 
| 204     invoker_.AsyncInvoke<ReturnT, FunctorT, HostT>( |  | 
| 205         posted_from, callback_posted_from, thread_, functor, callback, |  | 
| 206         callback_host, id); |  | 
| 207     return true; |  | 
| 208   } |  | 
| 209 |  | 
| 210  private: |  | 
| 211   // Callback when |thread_| is destroyed. |  | 
| 212   void ThreadDestroyed(); |  | 
| 213 |  | 
| 214   CriticalSection crit_; |  | 
| 215   Thread* thread_ GUARDED_BY(crit_); |  | 
| 216   AsyncInvoker invoker_ GUARDED_BY(crit_); |  | 
| 217 }; |  | 
| 218 |  | 
| 219 }  // namespace rtc |  | 
| 220 | 18 | 
| 221 #endif  // WEBRTC_BASE_ASYNCINVOKER_H_ | 19 #endif  // WEBRTC_BASE_ASYNCINVOKER_H_ | 
| OLD | NEW | 
|---|