blob: 175c6b7e0a13ab1fe11d229900e147e39ca6fe12 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2013 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
11// This file contains Macros for creating proxies for webrtc MediaStream and
12// PeerConnection classes.
deadbeefb10f32f2017-02-08 01:38:21 -080013// TODO(deadbeef): Move this to pc/; this is part of the implementation.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000014
15//
16// Example usage:
17//
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000018// class TestInterface : public rtc::RefCountInterface {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000019// public:
20// std::string FooA() = 0;
21// std::string FooB(bool arg1) const = 0;
nisse72c8d2b2016-04-15 03:49:07 -070022// std::string FooC(bool arg1) = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000023// };
24//
25// Note that return types can not be a const reference.
26//
27// class Test : public TestInterface {
28// ... implementation of the interface.
29// };
30//
31// BEGIN_PROXY_MAP(Test)
deadbeefd99a2002017-01-18 08:55:23 -080032// PROXY_SIGNALING_THREAD_DESTRUCTOR()
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033// PROXY_METHOD0(std::string, FooA)
34// PROXY_CONSTMETHOD1(std::string, FooB, arg1)
nisse72c8d2b2016-04-15 03:49:07 -070035// PROXY_WORKER_METHOD1(std::string, FooC, arg1)
deadbeefd99a2002017-01-18 08:55:23 -080036// END_PROXY_MAP()
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037//
deadbeefd99a2002017-01-18 08:55:23 -080038// Where the destructor and first two methods are invoked on the signaling
39// thread, and the third is invoked on the worker thread.
nisse72c8d2b2016-04-15 03:49:07 -070040//
41// The proxy can be created using
42//
43// TestProxy::Create(Thread* signaling_thread, Thread* worker_thread,
44// TestInterface*).
45//
46// The variant defined with BEGIN_SIGNALING_PROXY_MAP is unaware of
47// the worker thread, and invokes all methods on the signaling thread.
deadbeefd99a2002017-01-18 08:55:23 -080048//
49// The variant defined with BEGIN_OWNED_PROXY_MAP does not use
50// refcounting, and instead just takes ownership of the object being proxied.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020052#ifndef API_PROXY_H_
53#define API_PROXY_H_
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054
kwibergd1fe2812016-04-27 06:47:29 -070055#include <memory>
oprypin803dc292017-02-01 01:55:59 -080056#include <utility>
kwibergd1fe2812016-04-27 06:47:29 -070057
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "rtc_base/event.h"
Niels Möller84255bb2017-10-06 13:43:23 +020059#include "rtc_base/refcountedobject.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020060#include "rtc_base/thread.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061
62namespace webrtc {
63
64template <typename R>
65class ReturnType {
66 public:
67 template<typename C, typename M>
68 void Invoke(C* c, M m) { r_ = (c->*m)(); }
deadbeefd99a2002017-01-18 08:55:23 -080069 template <typename C, typename M, typename T1>
70 void Invoke(C* c, M m, T1 a1) {
71 r_ = (c->*m)(std::move(a1));
72 }
73 template <typename C, typename M, typename T1, typename T2>
74 void Invoke(C* c, M m, T1 a1, T2 a2) {
75 r_ = (c->*m)(std::move(a1), std::move(a2));
76 }
77 template <typename C, typename M, typename T1, typename T2, typename T3>
78 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) {
79 r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3));
80 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +000081 template<typename C, typename M, typename T1, typename T2, typename T3,
82 typename T4>
83 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4) {
deadbeefd99a2002017-01-18 08:55:23 -080084 r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3), std::move(a4));
perkj@webrtc.org81134d02015-01-12 08:30:16 +000085 }
86 template<typename C, typename M, typename T1, typename T2, typename T3,
87 typename T4, typename T5>
88 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
deadbeefd99a2002017-01-18 08:55:23 -080089 r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3), std::move(a4),
90 std::move(a5));
perkj@webrtc.org81134d02015-01-12 08:30:16 +000091 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092
deadbeefd99a2002017-01-18 08:55:23 -080093 R moved_result() { return std::move(r_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000094
95 private:
96 R r_;
97};
98
99template <>
100class ReturnType<void> {
101 public:
102 template<typename C, typename M>
103 void Invoke(C* c, M m) { (c->*m)(); }
deadbeefd99a2002017-01-18 08:55:23 -0800104 template <typename C, typename M, typename T1>
105 void Invoke(C* c, M m, T1 a1) {
106 (c->*m)(std::move(a1));
107 }
108 template <typename C, typename M, typename T1, typename T2>
109 void Invoke(C* c, M m, T1 a1, T2 a2) {
110 (c->*m)(std::move(a1), std::move(a2));
111 }
112 template <typename C, typename M, typename T1, typename T2, typename T3>
113 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) {
114 (c->*m)(std::move(a1), std::move(a2), std::move(a3));
115 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116
deadbeefd99a2002017-01-18 08:55:23 -0800117 void moved_result() {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000118};
119
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000120namespace internal {
121
122class SynchronousMethodCall
123 : public rtc::MessageData,
124 public rtc::MessageHandler {
125 public:
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000126 explicit SynchronousMethodCall(rtc::MessageHandler* proxy)
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000127 : e_(), proxy_(proxy) {}
128 ~SynchronousMethodCall() {}
129
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700130 void Invoke(const rtc::Location& posted_from, rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000131 if (t->IsCurrent()) {
deadbeef8d60a942017-02-27 14:47:33 -0800132 proxy_->OnMessage(nullptr);
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000133 } else {
134 e_.reset(new rtc::Event(false, false));
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700135 t->Post(posted_from, this, 0);
andresp@webrtc.org53d90122015-02-09 14:19:09 +0000136 e_->Wait(rtc::Event::kForever);
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000137 }
138 }
139
140 private:
deadbeef8d60a942017-02-27 14:47:33 -0800141 void OnMessage(rtc::Message*) {
142 proxy_->OnMessage(nullptr);
143 e_->Set();
144 }
kwibergd1fe2812016-04-27 06:47:29 -0700145 std::unique_ptr<rtc::Event> e_;
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000146 rtc::MessageHandler* proxy_;
147};
148
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000149} // namespace internal
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000150
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151template <typename C, typename R>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000152class MethodCall0 : public rtc::Message,
153 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000154 public:
155 typedef R (C::*Method)();
156 MethodCall0(C* c, Method m) : c_(c), m_(m) {}
157
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700158 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
159 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800160 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161 }
162
163 private:
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000164 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000165
166 C* c_;
167 Method m_;
168 ReturnType<R> r_;
169};
170
171template <typename C, typename R>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000172class ConstMethodCall0 : public rtc::Message,
173 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 public:
175 typedef R (C::*Method)() const;
176 ConstMethodCall0(C* c, Method m) : c_(c), m_(m) {}
177
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700178 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
179 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800180 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181 }
182
183 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000184 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000185
186 C* c_;
187 Method m_;
188 ReturnType<R> r_;
189};
190
191template <typename C, typename R, typename T1>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000192class MethodCall1 : public rtc::Message,
193 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000194 public:
195 typedef R (C::*Method)(T1 a1);
deadbeefd99a2002017-01-18 08:55:23 -0800196 MethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(std::move(a1)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000197
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700198 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
199 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800200 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000201 }
202
203 private:
deadbeefd99a2002017-01-18 08:55:23 -0800204 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, std::move(a1_)); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205
206 C* c_;
207 Method m_;
208 ReturnType<R> r_;
209 T1 a1_;
210};
211
212template <typename C, typename R, typename T1>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000213class ConstMethodCall1 : public rtc::Message,
214 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000215 public:
216 typedef R (C::*Method)(T1 a1) const;
deadbeefd99a2002017-01-18 08:55:23 -0800217 ConstMethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(std::move(a1)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000218
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700219 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
220 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800221 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222 }
223
224 private:
deadbeefd99a2002017-01-18 08:55:23 -0800225 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, std::move(a1_)); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226
227 C* c_;
228 Method m_;
229 ReturnType<R> r_;
230 T1 a1_;
231};
232
233template <typename C, typename R, typename T1, typename T2>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000234class MethodCall2 : public rtc::Message,
235 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 public:
237 typedef R (C::*Method)(T1 a1, T2 a2);
deadbeefd99a2002017-01-18 08:55:23 -0800238 MethodCall2(C* c, Method m, T1 a1, T2 a2)
239 : c_(c), m_(m), a1_(std::move(a1)), a2_(std::move(a2)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700241 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
242 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800243 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244 }
245
246 private:
deadbeefd99a2002017-01-18 08:55:23 -0800247 void OnMessage(rtc::Message*) {
248 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_));
249 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250
251 C* c_;
252 Method m_;
253 ReturnType<R> r_;
254 T1 a1_;
255 T2 a2_;
256};
257
258template <typename C, typename R, typename T1, typename T2, typename T3>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000259class MethodCall3 : public rtc::Message,
260 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261 public:
262 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3);
263 MethodCall3(C* c, Method m, T1 a1, T2 a2, T3 a3)
deadbeefd99a2002017-01-18 08:55:23 -0800264 : c_(c),
265 m_(m),
266 a1_(std::move(a1)),
267 a2_(std::move(a2)),
268 a3_(std::move(a3)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000269
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700270 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
271 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800272 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000273 }
274
275 private:
deadbeefd99a2002017-01-18 08:55:23 -0800276 void OnMessage(rtc::Message*) {
277 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_));
278 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000279
280 C* c_;
281 Method m_;
282 ReturnType<R> r_;
283 T1 a1_;
284 T2 a2_;
285 T3 a3_;
286};
287
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000288template <typename C, typename R, typename T1, typename T2, typename T3,
289 typename T4>
290class MethodCall4 : public rtc::Message,
291 public rtc::MessageHandler {
292 public:
293 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4);
294 MethodCall4(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4)
deadbeefd99a2002017-01-18 08:55:23 -0800295 : c_(c),
296 m_(m),
297 a1_(std::move(a1)),
298 a2_(std::move(a2)),
299 a3_(std::move(a3)),
300 a4_(std::move(a4)) {}
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000301
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700302 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
303 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800304 return r_.moved_result();
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000305 }
306
307 private:
deadbeefd99a2002017-01-18 08:55:23 -0800308 void OnMessage(rtc::Message*) {
309 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_),
310 std::move(a4_));
311 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000312
313 C* c_;
314 Method m_;
315 ReturnType<R> r_;
316 T1 a1_;
317 T2 a2_;
318 T3 a3_;
319 T4 a4_;
320};
321
322template <typename C, typename R, typename T1, typename T2, typename T3,
323 typename T4, typename T5>
324class MethodCall5 : public rtc::Message,
325 public rtc::MessageHandler {
326 public:
327 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
328 MethodCall5(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
deadbeefd99a2002017-01-18 08:55:23 -0800329 : c_(c),
330 m_(m),
331 a1_(std::move(a1)),
332 a2_(std::move(a2)),
333 a3_(std::move(a3)),
334 a4_(std::move(a4)),
335 a5_(std::move(a5)) {}
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000336
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700337 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
338 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800339 return r_.moved_result();
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000340 }
341
342 private:
deadbeefd99a2002017-01-18 08:55:23 -0800343 void OnMessage(rtc::Message*) {
344 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_),
345 std::move(a4_), std::move(a5_));
346 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000347
348 C* c_;
349 Method m_;
350 ReturnType<R> r_;
351 T1 a1_;
352 T2 a2_;
353 T3 a3_;
354 T4 a4_;
355 T5 a5_;
356};
357
oprypin803dc292017-02-01 01:55:59 -0800358
deadbeefd99a2002017-01-18 08:55:23 -0800359// Helper macros to reduce code duplication.
deadbeefe814a0d2017-02-25 18:15:09 -0800360#define PROXY_MAP_BOILERPLATE(c) \
361 template <class INTERNAL_CLASS> \
362 class c##ProxyWithInternal; \
363 typedef c##ProxyWithInternal<c##Interface> c##Proxy; \
364 template <class INTERNAL_CLASS> \
365 class c##ProxyWithInternal : public c##Interface { \
366 protected: \
367 typedef c##Interface C; \
368 \
369 public: \
370 const INTERNAL_CLASS* internal() const { return c_; } \
371 INTERNAL_CLASS* internal() { return c_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000372
oprypin803dc292017-02-01 01:55:59 -0800373#define END_PROXY_MAP() \
374 };
375
deadbeefd99a2002017-01-18 08:55:23 -0800376#define SIGNALING_PROXY_MAP_BOILERPLATE(c) \
377 protected: \
378 c##ProxyWithInternal(rtc::Thread* signaling_thread, INTERNAL_CLASS* c) \
379 : signaling_thread_(signaling_thread), c_(c) {} \
380 \
381 private: \
382 mutable rtc::Thread* signaling_thread_;
383
384#define WORKER_PROXY_MAP_BOILERPLATE(c) \
385 protected: \
386 c##ProxyWithInternal(rtc::Thread* signaling_thread, \
387 rtc::Thread* worker_thread, INTERNAL_CLASS* c) \
388 : signaling_thread_(signaling_thread), \
389 worker_thread_(worker_thread), \
390 c_(c) {} \
391 \
392 private: \
393 mutable rtc::Thread* signaling_thread_; \
394 mutable rtc::Thread* worker_thread_;
395
396// Note that the destructor is protected so that the proxy can only be
397// destroyed via RefCountInterface.
398#define REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
399 protected: \
400 ~c##ProxyWithInternal() { \
401 MethodCall0<c##ProxyWithInternal, void> call( \
402 this, &c##ProxyWithInternal::DestroyInternal); \
403 call.Marshal(RTC_FROM_HERE, destructor_thread()); \
404 } \
405 \
406 private: \
407 void DestroyInternal() { c_ = nullptr; } \
408 rtc::scoped_refptr<INTERNAL_CLASS> c_;
409
deadbeefe814a0d2017-02-25 18:15:09 -0800410// Note: This doesn't use a unique_ptr, because it intends to handle a corner
411// case where an object's deletion triggers a callback that calls back into
412// this proxy object. If relying on a unique_ptr to delete the object, its
413// inner pointer would be set to null before this reentrant callback would have
414// a chance to run, resulting in a segfault.
deadbeefd99a2002017-01-18 08:55:23 -0800415#define OWNED_PROXY_MAP_BOILERPLATE(c) \
416 public: \
417 ~c##ProxyWithInternal() { \
418 MethodCall0<c##ProxyWithInternal, void> call( \
419 this, &c##ProxyWithInternal::DestroyInternal); \
420 call.Marshal(RTC_FROM_HERE, destructor_thread()); \
421 } \
422 \
423 private: \
deadbeefe814a0d2017-02-25 18:15:09 -0800424 void DestroyInternal() { delete c_; } \
425 INTERNAL_CLASS* c_;
deadbeefd99a2002017-01-18 08:55:23 -0800426
427#define BEGIN_SIGNALING_PROXY_MAP(c) \
428 PROXY_MAP_BOILERPLATE(c) \
429 SIGNALING_PROXY_MAP_BOILERPLATE(c) \
430 REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
431 public: \
432 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \
433 rtc::Thread* signaling_thread, INTERNAL_CLASS* c) { \
434 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \
435 c); \
436 }
437
438#define BEGIN_PROXY_MAP(c) \
439 PROXY_MAP_BOILERPLATE(c) \
440 WORKER_PROXY_MAP_BOILERPLATE(c) \
441 REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
442 public: \
443 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \
444 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, \
445 INTERNAL_CLASS* c) { \
446 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \
447 worker_thread, c); \
448 }
449
deadbeefe814a0d2017-02-25 18:15:09 -0800450#define BEGIN_OWNED_PROXY_MAP(c) \
451 PROXY_MAP_BOILERPLATE(c) \
452 WORKER_PROXY_MAP_BOILERPLATE(c) \
453 OWNED_PROXY_MAP_BOILERPLATE(c) \
454 public: \
455 static std::unique_ptr<c##Interface> Create( \
456 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, \
457 std::unique_ptr<INTERNAL_CLASS> c) { \
458 return std::unique_ptr<c##Interface>(new c##ProxyWithInternal( \
459 signaling_thread, worker_thread, c.release())); \
deadbeefd99a2002017-01-18 08:55:23 -0800460 }
461
462#define PROXY_SIGNALING_THREAD_DESTRUCTOR() \
463 private: \
464 rtc::Thread* destructor_thread() const { return signaling_thread_; } \
465 \
oprypin803dc292017-02-01 01:55:59 -0800466 public: // NOLINTNEXTLINE
deadbeefd99a2002017-01-18 08:55:23 -0800467
468#define PROXY_WORKER_THREAD_DESTRUCTOR() \
469 private: \
470 rtc::Thread* destructor_thread() const { return worker_thread_; } \
471 \
oprypin803dc292017-02-01 01:55:59 -0800472 public: // NOLINTNEXTLINE
deadbeefd99a2002017-01-18 08:55:23 -0800473
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700474#define PROXY_METHOD0(r, method) \
475 r method() override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800476 MethodCall0<C, r> call(c_, &C::method); \
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700477 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000478 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000479
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700480#define PROXY_CONSTMETHOD0(r, method) \
481 r method() const override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800482 ConstMethodCall0<C, r> call(c_, &C::method); \
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700483 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000484 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000485
deadbeefe814a0d2017-02-25 18:15:09 -0800486#define PROXY_METHOD1(r, method, t1) \
487 r method(t1 a1) override { \
488 MethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
489 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000490 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000491
deadbeefe814a0d2017-02-25 18:15:09 -0800492#define PROXY_CONSTMETHOD1(r, method, t1) \
493 r method(t1 a1) const override { \
494 ConstMethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
495 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000496 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000497
deadbeefe814a0d2017-02-25 18:15:09 -0800498#define PROXY_METHOD2(r, method, t1, t2) \
499 r method(t1 a1, t2 a2) override { \
500 MethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
501 std::move(a2)); \
502 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000503 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000504
deadbeefe814a0d2017-02-25 18:15:09 -0800505#define PROXY_METHOD3(r, method, t1, t2, t3) \
506 r method(t1 a1, t2 a2, t3 a3) override { \
507 MethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
508 std::move(a2), std::move(a3)); \
509 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800510 }
511
512#define PROXY_METHOD4(r, method, t1, t2, t3, t4) \
513 r method(t1 a1, t2 a2, t3 a3, t4 a4) override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800514 MethodCall4<C, r, t1, t2, t3, t4> call(c_, &C::method, std::move(a1), \
515 std::move(a2), std::move(a3), \
516 std::move(a4)); \
deadbeefd99a2002017-01-18 08:55:23 -0800517 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
518 }
519
deadbeefe814a0d2017-02-25 18:15:09 -0800520#define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \
521 r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \
522 MethodCall5<C, r, t1, t2, t3, t4, t5> call(c_, &C::method, std::move(a1), \
523 std::move(a2), std::move(a3), \
524 std::move(a4), std::move(a5)); \
525 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
nisse5b68ab52016-04-07 07:45:54 -0700526 }
527
528// Define methods which should be invoked on the worker thread.
deadbeefd99a2002017-01-18 08:55:23 -0800529#define PROXY_WORKER_METHOD0(r, method) \
530 r method() override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800531 MethodCall0<C, r> call(c_, &C::method); \
deadbeefd99a2002017-01-18 08:55:23 -0800532 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
nisse5b68ab52016-04-07 07:45:54 -0700533 }
534
deadbeefd99a2002017-01-18 08:55:23 -0800535#define PROXY_WORKER_CONSTMETHOD0(r, method) \
536 r method() const override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800537 ConstMethodCall0<C, r> call(c_, &C::method); \
deadbeefd99a2002017-01-18 08:55:23 -0800538 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000539 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000540
deadbeefe814a0d2017-02-25 18:15:09 -0800541#define PROXY_WORKER_METHOD1(r, method, t1) \
542 r method(t1 a1) override { \
543 MethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
544 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800545 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000546
deadbeefe814a0d2017-02-25 18:15:09 -0800547#define PROXY_WORKER_CONSTMETHOD1(r, method, t1) \
548 r method(t1 a1) const override { \
549 ConstMethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
550 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800551 }
552
deadbeefe814a0d2017-02-25 18:15:09 -0800553#define PROXY_WORKER_METHOD2(r, method, t1, t2) \
554 r method(t1 a1, t2 a2) override { \
555 MethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
556 std::move(a2)); \
557 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800558 }
559
deadbeefe814a0d2017-02-25 18:15:09 -0800560#define PROXY_WORKER_CONSTMETHOD2(r, method, t1, t2) \
561 r method(t1 a1, t2 a2) const override { \
562 ConstMethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
563 std::move(a2)); \
564 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
565 }
566
567#define PROXY_WORKER_METHOD3(r, method, t1, t2, t3) \
568 r method(t1 a1, t2 a2, t3 a3) override { \
569 MethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
570 std::move(a2), std::move(a3)); \
571 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
572 }
573
574#define PROXY_WORKER_CONSTMETHOD3(r, method, t1, t2) \
575 r method(t1 a1, t2 a2, t3 a3) const override { \
576 ConstMethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
577 std::move(a2), std::move(a3)); \
578 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800579 }
580
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000581} // namespace webrtc
582
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200583#endif // API_PROXY_H_