blob: d172eee0a6bc32cdde3d9d51b1dae0ed9e1471f9 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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_INL_H_
12#define WEBRTC_BASE_ASYNCINVOKER_INL_H_
13
deadbeef162cb532017-02-23 17:10:07 -080014#include "webrtc/base/atomicops.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000015#include "webrtc/base/bind.h"
16#include "webrtc/base/callback.h"
17#include "webrtc/base/criticalsection.h"
18#include "webrtc/base/messagehandler.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000019#include "webrtc/base/sigslot.h"
20#include "webrtc/base/thread.h"
21
22namespace rtc {
23
24class AsyncInvoker;
25
26// Helper class for AsyncInvoker. Runs a task and triggers a callback
deadbeefa8bc1a12017-02-17 18:06:26 -080027// on the calling thread if necessary.
28class AsyncClosure {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000029 public:
deadbeef162cb532017-02-23 17:10:07 -080030 explicit AsyncClosure(AsyncInvoker* invoker) : invoker_(invoker) {}
31 virtual ~AsyncClosure();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000032 // Runs the asynchronous task, and triggers a callback to the calling
33 // thread if needed. Should be called from the target thread.
34 virtual void Execute() = 0;
deadbeef162cb532017-02-23 17:10:07 -080035
36 protected:
37 AsyncInvoker* invoker_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000038};
39
40// Simple closure that doesn't trigger a callback for the calling thread.
41template <class FunctorT>
42class FireAndForgetAsyncClosure : public AsyncClosure {
43 public:
deadbeef162cb532017-02-23 17:10:07 -080044 explicit FireAndForgetAsyncClosure(AsyncInvoker* invoker,
45 const FunctorT& functor)
46 : AsyncClosure(invoker), functor_(functor) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047 virtual void Execute() {
48 functor_();
49 }
50 private:
51 FunctorT functor_;
52};
53
54// Base class for closures that may trigger a callback for the calling thread.
55// Listens for the "destroyed" signals from the calling thread and the invoker,
56// and cancels the callback to the calling thread if either is destroyed.
57class NotifyingAsyncClosureBase : public AsyncClosure,
58 public sigslot::has_slots<> {
59 public:
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000060 ~NotifyingAsyncClosureBase() override;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000061
62 protected:
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070063 NotifyingAsyncClosureBase(AsyncInvoker* invoker,
64 const Location& callback_posted_from,
65 Thread* calling_thread);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000066 void TriggerCallback();
67 void SetCallback(const Callback0<void>& callback) {
68 CritScope cs(&crit_);
69 callback_ = callback;
70 }
71 bool CallbackCanceled() const { return calling_thread_ == NULL; }
72
73 private:
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070074 Location callback_posted_from_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000075 Callback0<void> callback_;
76 CriticalSection crit_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000077 Thread* calling_thread_;
78
79 void CancelCallback();
80};
81
82// Closures that have a non-void return value and require a callback.
83template <class ReturnT, class FunctorT, class HostT>
84class NotifyingAsyncClosure : public NotifyingAsyncClosureBase {
85 public:
86 NotifyingAsyncClosure(AsyncInvoker* invoker,
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070087 const Location& callback_posted_from,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000088 Thread* calling_thread,
89 const FunctorT& functor,
90 void (HostT::*callback)(ReturnT),
91 HostT* callback_host)
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070092 : NotifyingAsyncClosureBase(invoker,
93 callback_posted_from,
94 calling_thread),
95 functor_(functor),
96 callback_(callback),
97 callback_host_(callback_host) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000098 virtual void Execute() {
99 ReturnT result = functor_();
100 if (!CallbackCanceled()) {
101 SetCallback(Callback0<void>(Bind(callback_, callback_host_, result)));
102 TriggerCallback();
103 }
104 }
105
106 private:
107 FunctorT functor_;
108 void (HostT::*callback_)(ReturnT);
109 HostT* callback_host_;
110};
111
112// Closures that have a void return value and require a callback.
113template <class FunctorT, class HostT>
114class NotifyingAsyncClosure<void, FunctorT, HostT>
115 : public NotifyingAsyncClosureBase {
116 public:
117 NotifyingAsyncClosure(AsyncInvoker* invoker,
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700118 const Location& callback_posted_from,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000119 Thread* calling_thread,
120 const FunctorT& functor,
121 void (HostT::*callback)(),
122 HostT* callback_host)
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700123 : NotifyingAsyncClosureBase(invoker,
124 callback_posted_from,
125 calling_thread),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000126 functor_(functor) {
127 SetCallback(Callback0<void>(Bind(callback, callback_host)));
128 }
129 virtual void Execute() {
130 functor_();
131 TriggerCallback();
132 }
133
134 private:
135 FunctorT functor_;
136};
137
138} // namespace rtc
139
140#endif // WEBRTC_BASE_ASYNCINVOKER_INL_H_