blob: 15fafa888b1fca715f28bb8b4161432f82f9e538 [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
14#include "webrtc/base/bind.h"
15#include "webrtc/base/callback.h"
16#include "webrtc/base/criticalsection.h"
17#include "webrtc/base/messagehandler.h"
deadbeef884a7282017-02-17 15:57:05 -080018#include "webrtc/base/refcount.h"
19#include "webrtc/base/scoped_ref_ptr.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000020#include "webrtc/base/sigslot.h"
21#include "webrtc/base/thread.h"
22
23namespace rtc {
24
25class AsyncInvoker;
26
27// Helper class for AsyncInvoker. Runs a task and triggers a callback
deadbeef884a7282017-02-17 15:57:05 -080028// on the calling thread if necessary. Instances are ref-counted so their
29// lifetime can be independent of AsyncInvoker.
30class AsyncClosure : public RefCountInterface {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000031 public:
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;
deadbeef884a7282017-02-17 15:57:05 -080035 protected:
36 ~AsyncClosure() override {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000037};
38
39// Simple closure that doesn't trigger a callback for the calling thread.
40template <class FunctorT>
41class FireAndForgetAsyncClosure : public AsyncClosure {
42 public:
43 explicit FireAndForgetAsyncClosure(const FunctorT& functor)
44 : functor_(functor) {}
45 virtual void Execute() {
46 functor_();
47 }
48 private:
49 FunctorT functor_;
50};
51
52// Base class for closures that may trigger a callback for the calling thread.
53// Listens for the "destroyed" signals from the calling thread and the invoker,
54// and cancels the callback to the calling thread if either is destroyed.
55class NotifyingAsyncClosureBase : public AsyncClosure,
56 public sigslot::has_slots<> {
57 public:
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000058 ~NotifyingAsyncClosureBase() override;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000059
60 protected:
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070061 NotifyingAsyncClosureBase(AsyncInvoker* invoker,
62 const Location& callback_posted_from,
63 Thread* calling_thread);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000064 void TriggerCallback();
65 void SetCallback(const Callback0<void>& callback) {
66 CritScope cs(&crit_);
67 callback_ = callback;
68 }
69 bool CallbackCanceled() const { return calling_thread_ == NULL; }
70
71 private:
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070072 AsyncInvoker* invoker_;
73 Location callback_posted_from_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000074 Callback0<void> callback_;
75 CriticalSection crit_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000076 Thread* calling_thread_;
77
78 void CancelCallback();
79};
80
81// Closures that have a non-void return value and require a callback.
82template <class ReturnT, class FunctorT, class HostT>
83class NotifyingAsyncClosure : public NotifyingAsyncClosureBase {
84 public:
85 NotifyingAsyncClosure(AsyncInvoker* invoker,
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070086 const Location& callback_posted_from,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000087 Thread* calling_thread,
88 const FunctorT& functor,
89 void (HostT::*callback)(ReturnT),
90 HostT* callback_host)
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070091 : NotifyingAsyncClosureBase(invoker,
92 callback_posted_from,
93 calling_thread),
94 functor_(functor),
95 callback_(callback),
96 callback_host_(callback_host) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000097 virtual void Execute() {
98 ReturnT result = functor_();
99 if (!CallbackCanceled()) {
100 SetCallback(Callback0<void>(Bind(callback_, callback_host_, result)));
101 TriggerCallback();
102 }
103 }
104
105 private:
106 FunctorT functor_;
107 void (HostT::*callback_)(ReturnT);
108 HostT* callback_host_;
109};
110
111// Closures that have a void return value and require a callback.
112template <class FunctorT, class HostT>
113class NotifyingAsyncClosure<void, FunctorT, HostT>
114 : public NotifyingAsyncClosureBase {
115 public:
116 NotifyingAsyncClosure(AsyncInvoker* invoker,
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700117 const Location& callback_posted_from,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000118 Thread* calling_thread,
119 const FunctorT& functor,
120 void (HostT::*callback)(),
121 HostT* callback_host)
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700122 : NotifyingAsyncClosureBase(invoker,
123 callback_posted_from,
124 calling_thread),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000125 functor_(functor) {
126 SetCallback(Callback0<void>(Bind(callback, callback_host)));
127 }
128 virtual void Execute() {
129 functor_();
130 TriggerCallback();
131 }
132
133 private:
134 FunctorT functor_;
135};
136
137} // namespace rtc
138
139#endif // WEBRTC_BASE_ASYNCINVOKER_INL_H_