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