Index: webrtc/base/asyncinvoker.h |
diff --git a/webrtc/base/asyncinvoker.h b/webrtc/base/asyncinvoker.h |
index fe1506d99f8688ca53f92d6f7b3da401dbe84107..e0264be20803c113e57ad0c8cb7a32289816c21c 100644 |
--- a/webrtc/base/asyncinvoker.h |
+++ b/webrtc/base/asyncinvoker.h |
@@ -144,7 +144,87 @@ class AsyncInvoker : public MessageHandler { |
DISALLOW_COPY_AND_ASSIGN(AsyncInvoker); |
}; |
-} // namespace rtc |
+// Similar to AsyncInvoker, but guards against the Thread being destroyed while |
+// there are outstanding dangling pointers to it. It will connect to the current |
+// thread in the constructor, and will get notified when that thread is |
+// destroyed. After GuardedAsyncInvoker is constructed, it can be used from |
+// other threads to post functors to the thread it was constructed on. If that |
+// thread dies, any further calls to AsyncInvoke() will be safely ignored. |
+class GuardedAsyncInvoker : public sigslot::has_slots<> { |
+ public: |
+ GuardedAsyncInvoker(); |
+ ~GuardedAsyncInvoker() override; |
+ |
+ // Synchronously execute all outstanding calls we own, and wait for calls to |
+ // complete before returning. Optionally filter by message id. The destructor |
+ // will not wait for outstanding calls, so if that behavior is desired, call |
+ // Flush() first. Returns false if the thread has died. |
+ bool Flush(uint32 id = MQID_ANY); |
+ |
+ // Call |functor| asynchronously with no callback upon completion. Returns |
+ // immediately. Returns false if the thread has died. |
+ template <class ReturnT, class FunctorT> |
+ bool AsyncInvoke(const FunctorT& functor, uint32 id = 0) { |
+ rtc::CritScope cs(&crit_); |
+ if (thread_ == nullptr) |
+ return false; |
+ invoker_.AsyncInvoke<ReturnT, FunctorT>(thread_, functor, id); |
+ return true; |
+ } |
+ |
+ // Call |functor| asynchronously with |delay_ms|, with no callback upon |
+ // completion. Returns immediately. Returns false if the thread has died. |
+ template <class ReturnT, class FunctorT> |
+ bool AsyncInvokeDelayed(const FunctorT& functor, |
+ uint32 delay_ms, |
+ uint32 id = 0) { |
+ rtc::CritScope cs(&crit_); |
+ if (thread_ == nullptr) |
+ return false; |
+ invoker_.AsyncInvokeDelayed<ReturnT, FunctorT>(thread_, functor, delay_ms, |
+ id); |
+ return true; |
+ } |
+ |
+ // Call |functor| asynchronously, calling |callback| when done. Returns false |
+ // if the thread has died. |
+ template <class ReturnT, class FunctorT, class HostT> |
+ bool AsyncInvoke(const FunctorT& functor, |
+ void (HostT::*callback)(ReturnT), |
+ HostT* callback_host, |
+ uint32 id = 0) { |
+ rtc::CritScope cs(&crit_); |
+ if (thread_ == nullptr) |
+ return false; |
+ invoker_.AsyncInvoke<ReturnT, FunctorT, HostT>(thread_, functor, callback, |
+ callback_host, id); |
+ return true; |
+ } |
+ |
+ // Call |functor| asynchronously calling |callback| when done. Overloaded for |
+ // void return. Returns false if the thread has died. |
+ template <class ReturnT, class FunctorT, class HostT> |
+ bool AsyncInvoke(const FunctorT& functor, |
+ void (HostT::*callback)(), |
+ HostT* callback_host, |
+ uint32 id = 0) { |
+ rtc::CritScope cs(&crit_); |
+ if (thread_ == nullptr) |
+ return false; |
+ invoker_.AsyncInvoke<ReturnT, FunctorT, HostT>(thread_, functor, callback, |
+ callback_host, id); |
+ return true; |
+ } |
+ |
+ private: |
+ // Callback when |thread_| is destroyed. |
+ void ThreadDestroyed(); |
+ CriticalSection crit_; |
+ Thread* thread_ GUARDED_BY(crit_); |
+ AsyncInvoker invoker_ GUARDED_BY(crit_); |
+}; |
+ |
+} // namespace rtc |
#endif // WEBRTC_BASE_ASYNCINVOKER_H_ |