1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2013 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker // This file contains Macros for creating proxies for webrtc MediaStream and 12*d9f75844SAndroid Build Coastguard Worker // PeerConnection classes. 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker // The proxied objects are initialized with either one or two thread 15*d9f75844SAndroid Build Coastguard Worker // objects that operations can be proxied to: The primary and secondary 16*d9f75844SAndroid Build Coastguard Worker // threads. 17*d9f75844SAndroid Build Coastguard Worker // In common usage, the primary thread will be the PeerConnection's 18*d9f75844SAndroid Build Coastguard Worker // signaling thread, and the secondary thread will be either the 19*d9f75844SAndroid Build Coastguard Worker // PeerConnection's worker thread or the PeerConnection's network thread. 20*d9f75844SAndroid Build Coastguard Worker 21*d9f75844SAndroid Build Coastguard Worker // 22*d9f75844SAndroid Build Coastguard Worker // Example usage: 23*d9f75844SAndroid Build Coastguard Worker // 24*d9f75844SAndroid Build Coastguard Worker // class TestInterface : public rtc::RefCountInterface { 25*d9f75844SAndroid Build Coastguard Worker // public: 26*d9f75844SAndroid Build Coastguard Worker // std::string FooA() = 0; 27*d9f75844SAndroid Build Coastguard Worker // std::string FooB(bool arg1) const = 0; 28*d9f75844SAndroid Build Coastguard Worker // std::string FooC(bool arg1) = 0; 29*d9f75844SAndroid Build Coastguard Worker // }; 30*d9f75844SAndroid Build Coastguard Worker // 31*d9f75844SAndroid Build Coastguard Worker // Note that return types can not be a const reference. 32*d9f75844SAndroid Build Coastguard Worker // 33*d9f75844SAndroid Build Coastguard Worker // class Test : public TestInterface { 34*d9f75844SAndroid Build Coastguard Worker // ... implementation of the interface. 35*d9f75844SAndroid Build Coastguard Worker // }; 36*d9f75844SAndroid Build Coastguard Worker // 37*d9f75844SAndroid Build Coastguard Worker // BEGIN_PROXY_MAP(Test) 38*d9f75844SAndroid Build Coastguard Worker // PROXY_PRIMARY_THREAD_DESTRUCTOR() 39*d9f75844SAndroid Build Coastguard Worker // PROXY_METHOD0(std::string, FooA) 40*d9f75844SAndroid Build Coastguard Worker // PROXY_CONSTMETHOD1(std::string, FooB, arg1) 41*d9f75844SAndroid Build Coastguard Worker // PROXY_SECONDARY_METHOD1(std::string, FooC, arg1) 42*d9f75844SAndroid Build Coastguard Worker // END_PROXY_MAP() 43*d9f75844SAndroid Build Coastguard Worker // 44*d9f75844SAndroid Build Coastguard Worker // Where the destructor and first two methods are invoked on the primary 45*d9f75844SAndroid Build Coastguard Worker // thread, and the third is invoked on the secondary thread. 46*d9f75844SAndroid Build Coastguard Worker // 47*d9f75844SAndroid Build Coastguard Worker // The proxy can be created using 48*d9f75844SAndroid Build Coastguard Worker // 49*d9f75844SAndroid Build Coastguard Worker // TestProxy::Create(Thread* signaling_thread, Thread* worker_thread, 50*d9f75844SAndroid Build Coastguard Worker // TestInterface*). 51*d9f75844SAndroid Build Coastguard Worker // 52*d9f75844SAndroid Build Coastguard Worker // The variant defined with BEGIN_PRIMARY_PROXY_MAP is unaware of 53*d9f75844SAndroid Build Coastguard Worker // the secondary thread, and invokes all methods on the primary thread. 54*d9f75844SAndroid Build Coastguard Worker // 55*d9f75844SAndroid Build Coastguard Worker 56*d9f75844SAndroid Build Coastguard Worker #ifndef PC_PROXY_H_ 57*d9f75844SAndroid Build Coastguard Worker #define PC_PROXY_H_ 58*d9f75844SAndroid Build Coastguard Worker 59*d9f75844SAndroid Build Coastguard Worker #include <stddef.h> 60*d9f75844SAndroid Build Coastguard Worker 61*d9f75844SAndroid Build Coastguard Worker #include <memory> 62*d9f75844SAndroid Build Coastguard Worker #include <string> 63*d9f75844SAndroid Build Coastguard Worker #include <tuple> 64*d9f75844SAndroid Build Coastguard Worker #include <type_traits> 65*d9f75844SAndroid Build Coastguard Worker #include <utility> 66*d9f75844SAndroid Build Coastguard Worker 67*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h" 68*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_base.h" 69*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/event.h" 70*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/string_utils.h" 71*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/rtc_export.h" 72*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h" 73*d9f75844SAndroid Build Coastguard Worker 74*d9f75844SAndroid Build Coastguard Worker #if !defined(RTC_DISABLE_PROXY_TRACE_EVENTS) && !defined(WEBRTC_CHROMIUM_BUILD) 75*d9f75844SAndroid Build Coastguard Worker #define RTC_DISABLE_PROXY_TRACE_EVENTS 76*d9f75844SAndroid Build Coastguard Worker #endif 77*d9f75844SAndroid Build Coastguard Worker 78*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 79*d9f75844SAndroid Build Coastguard Worker namespace proxy_internal { 80*d9f75844SAndroid Build Coastguard Worker 81*d9f75844SAndroid Build Coastguard Worker // Class for tracing the lifetime of MethodCall::Marshal. 82*d9f75844SAndroid Build Coastguard Worker class ScopedTrace { 83*d9f75844SAndroid Build Coastguard Worker public: 84*d9f75844SAndroid Build Coastguard Worker explicit ScopedTrace(const char* class_and_method_name); 85*d9f75844SAndroid Build Coastguard Worker ~ScopedTrace(); 86*d9f75844SAndroid Build Coastguard Worker 87*d9f75844SAndroid Build Coastguard Worker private: 88*d9f75844SAndroid Build Coastguard Worker [[maybe_unused]] const char* const class_and_method_name_; 89*d9f75844SAndroid Build Coastguard Worker }; 90*d9f75844SAndroid Build Coastguard Worker } // namespace proxy_internal 91*d9f75844SAndroid Build Coastguard Worker 92*d9f75844SAndroid Build Coastguard Worker template <typename R> 93*d9f75844SAndroid Build Coastguard Worker class ReturnType { 94*d9f75844SAndroid Build Coastguard Worker public: 95*d9f75844SAndroid Build Coastguard Worker template <typename C, typename M, typename... Args> Invoke(C * c,M m,Args &&...args)96*d9f75844SAndroid Build Coastguard Worker void Invoke(C* c, M m, Args&&... args) { 97*d9f75844SAndroid Build Coastguard Worker r_ = (c->*m)(std::forward<Args>(args)...); 98*d9f75844SAndroid Build Coastguard Worker } 99*d9f75844SAndroid Build Coastguard Worker moved_result()100*d9f75844SAndroid Build Coastguard Worker R moved_result() { return std::move(r_); } 101*d9f75844SAndroid Build Coastguard Worker 102*d9f75844SAndroid Build Coastguard Worker private: 103*d9f75844SAndroid Build Coastguard Worker R r_; 104*d9f75844SAndroid Build Coastguard Worker }; 105*d9f75844SAndroid Build Coastguard Worker 106*d9f75844SAndroid Build Coastguard Worker template <> 107*d9f75844SAndroid Build Coastguard Worker class ReturnType<void> { 108*d9f75844SAndroid Build Coastguard Worker public: 109*d9f75844SAndroid Build Coastguard Worker template <typename C, typename M, typename... Args> Invoke(C * c,M m,Args &&...args)110*d9f75844SAndroid Build Coastguard Worker void Invoke(C* c, M m, Args&&... args) { 111*d9f75844SAndroid Build Coastguard Worker (c->*m)(std::forward<Args>(args)...); 112*d9f75844SAndroid Build Coastguard Worker } 113*d9f75844SAndroid Build Coastguard Worker moved_result()114*d9f75844SAndroid Build Coastguard Worker void moved_result() {} 115*d9f75844SAndroid Build Coastguard Worker }; 116*d9f75844SAndroid Build Coastguard Worker 117*d9f75844SAndroid Build Coastguard Worker template <typename C, typename R, typename... Args> 118*d9f75844SAndroid Build Coastguard Worker class MethodCall { 119*d9f75844SAndroid Build Coastguard Worker public: 120*d9f75844SAndroid Build Coastguard Worker typedef R (C::*Method)(Args...); MethodCall(C * c,Method m,Args &&...args)121*d9f75844SAndroid Build Coastguard Worker MethodCall(C* c, Method m, Args&&... args) 122*d9f75844SAndroid Build Coastguard Worker : c_(c), 123*d9f75844SAndroid Build Coastguard Worker m_(m), 124*d9f75844SAndroid Build Coastguard Worker args_(std::forward_as_tuple(std::forward<Args>(args)...)) {} 125*d9f75844SAndroid Build Coastguard Worker Marshal(rtc::Thread * t)126*d9f75844SAndroid Build Coastguard Worker R Marshal(rtc::Thread* t) { 127*d9f75844SAndroid Build Coastguard Worker if (t->IsCurrent()) { 128*d9f75844SAndroid Build Coastguard Worker Invoke(std::index_sequence_for<Args...>()); 129*d9f75844SAndroid Build Coastguard Worker } else { 130*d9f75844SAndroid Build Coastguard Worker t->PostTask([this] { 131*d9f75844SAndroid Build Coastguard Worker Invoke(std::index_sequence_for<Args...>()); 132*d9f75844SAndroid Build Coastguard Worker event_.Set(); 133*d9f75844SAndroid Build Coastguard Worker }); 134*d9f75844SAndroid Build Coastguard Worker event_.Wait(rtc::Event::kForever); 135*d9f75844SAndroid Build Coastguard Worker } 136*d9f75844SAndroid Build Coastguard Worker return r_.moved_result(); 137*d9f75844SAndroid Build Coastguard Worker } 138*d9f75844SAndroid Build Coastguard Worker 139*d9f75844SAndroid Build Coastguard Worker private: 140*d9f75844SAndroid Build Coastguard Worker template <size_t... Is> Invoke(std::index_sequence<Is...>)141*d9f75844SAndroid Build Coastguard Worker void Invoke(std::index_sequence<Is...>) { 142*d9f75844SAndroid Build Coastguard Worker r_.Invoke(c_, m_, std::move(std::get<Is>(args_))...); 143*d9f75844SAndroid Build Coastguard Worker } 144*d9f75844SAndroid Build Coastguard Worker 145*d9f75844SAndroid Build Coastguard Worker C* c_; 146*d9f75844SAndroid Build Coastguard Worker Method m_; 147*d9f75844SAndroid Build Coastguard Worker ReturnType<R> r_; 148*d9f75844SAndroid Build Coastguard Worker std::tuple<Args&&...> args_; 149*d9f75844SAndroid Build Coastguard Worker rtc::Event event_; 150*d9f75844SAndroid Build Coastguard Worker }; 151*d9f75844SAndroid Build Coastguard Worker 152*d9f75844SAndroid Build Coastguard Worker template <typename C, typename R, typename... Args> 153*d9f75844SAndroid Build Coastguard Worker class ConstMethodCall { 154*d9f75844SAndroid Build Coastguard Worker public: 155*d9f75844SAndroid Build Coastguard Worker typedef R (C::*Method)(Args...) const; ConstMethodCall(const C * c,Method m,Args &&...args)156*d9f75844SAndroid Build Coastguard Worker ConstMethodCall(const C* c, Method m, Args&&... args) 157*d9f75844SAndroid Build Coastguard Worker : c_(c), 158*d9f75844SAndroid Build Coastguard Worker m_(m), 159*d9f75844SAndroid Build Coastguard Worker args_(std::forward_as_tuple(std::forward<Args>(args)...)) {} 160*d9f75844SAndroid Build Coastguard Worker Marshal(rtc::Thread * t)161*d9f75844SAndroid Build Coastguard Worker R Marshal(rtc::Thread* t) { 162*d9f75844SAndroid Build Coastguard Worker if (t->IsCurrent()) { 163*d9f75844SAndroid Build Coastguard Worker Invoke(std::index_sequence_for<Args...>()); 164*d9f75844SAndroid Build Coastguard Worker } else { 165*d9f75844SAndroid Build Coastguard Worker t->PostTask([this] { 166*d9f75844SAndroid Build Coastguard Worker Invoke(std::index_sequence_for<Args...>()); 167*d9f75844SAndroid Build Coastguard Worker event_.Set(); 168*d9f75844SAndroid Build Coastguard Worker }); 169*d9f75844SAndroid Build Coastguard Worker event_.Wait(rtc::Event::kForever); 170*d9f75844SAndroid Build Coastguard Worker } 171*d9f75844SAndroid Build Coastguard Worker return r_.moved_result(); 172*d9f75844SAndroid Build Coastguard Worker } 173*d9f75844SAndroid Build Coastguard Worker 174*d9f75844SAndroid Build Coastguard Worker private: 175*d9f75844SAndroid Build Coastguard Worker template <size_t... Is> Invoke(std::index_sequence<Is...>)176*d9f75844SAndroid Build Coastguard Worker void Invoke(std::index_sequence<Is...>) { 177*d9f75844SAndroid Build Coastguard Worker r_.Invoke(c_, m_, std::move(std::get<Is>(args_))...); 178*d9f75844SAndroid Build Coastguard Worker } 179*d9f75844SAndroid Build Coastguard Worker 180*d9f75844SAndroid Build Coastguard Worker const C* c_; 181*d9f75844SAndroid Build Coastguard Worker Method m_; 182*d9f75844SAndroid Build Coastguard Worker ReturnType<R> r_; 183*d9f75844SAndroid Build Coastguard Worker std::tuple<Args&&...> args_; 184*d9f75844SAndroid Build Coastguard Worker rtc::Event event_; 185*d9f75844SAndroid Build Coastguard Worker }; 186*d9f75844SAndroid Build Coastguard Worker 187*d9f75844SAndroid Build Coastguard Worker #define PROXY_STRINGIZE_IMPL(x) #x 188*d9f75844SAndroid Build Coastguard Worker #define PROXY_STRINGIZE(x) PROXY_STRINGIZE_IMPL(x) 189*d9f75844SAndroid Build Coastguard Worker 190*d9f75844SAndroid Build Coastguard Worker // Helper macros to reduce code duplication. 191*d9f75844SAndroid Build Coastguard Worker #define PROXY_MAP_BOILERPLATE(class_name) \ 192*d9f75844SAndroid Build Coastguard Worker template <class INTERNAL_CLASS> \ 193*d9f75844SAndroid Build Coastguard Worker class class_name##ProxyWithInternal; \ 194*d9f75844SAndroid Build Coastguard Worker typedef class_name##ProxyWithInternal<class_name##Interface> \ 195*d9f75844SAndroid Build Coastguard Worker class_name##Proxy; \ 196*d9f75844SAndroid Build Coastguard Worker template <class INTERNAL_CLASS> \ 197*d9f75844SAndroid Build Coastguard Worker class class_name##ProxyWithInternal : public class_name##Interface { \ 198*d9f75844SAndroid Build Coastguard Worker protected: \ 199*d9f75844SAndroid Build Coastguard Worker static constexpr char proxy_name_[] = #class_name "Proxy"; \ 200*d9f75844SAndroid Build Coastguard Worker typedef class_name##Interface C; \ 201*d9f75844SAndroid Build Coastguard Worker \ 202*d9f75844SAndroid Build Coastguard Worker public: \ 203*d9f75844SAndroid Build Coastguard Worker const INTERNAL_CLASS* internal() const { return c(); } \ 204*d9f75844SAndroid Build Coastguard Worker INTERNAL_CLASS* internal() { return c(); } 205*d9f75844SAndroid Build Coastguard Worker 206*d9f75844SAndroid Build Coastguard Worker // clang-format off 207*d9f75844SAndroid Build Coastguard Worker // clang-format would put the semicolon alone, 208*d9f75844SAndroid Build Coastguard Worker // leading to a presubmit error (cpplint.py) 209*d9f75844SAndroid Build Coastguard Worker #define END_PROXY_MAP(class_name) \ 210*d9f75844SAndroid Build Coastguard Worker }; \ 211*d9f75844SAndroid Build Coastguard Worker template <class INTERNAL_CLASS> \ 212*d9f75844SAndroid Build Coastguard Worker constexpr char class_name##ProxyWithInternal<INTERNAL_CLASS>::proxy_name_[]; 213*d9f75844SAndroid Build Coastguard Worker // clang-format on 214*d9f75844SAndroid Build Coastguard Worker 215*d9f75844SAndroid Build Coastguard Worker #define PRIMARY_PROXY_MAP_BOILERPLATE(class_name) \ 216*d9f75844SAndroid Build Coastguard Worker protected: \ 217*d9f75844SAndroid Build Coastguard Worker class_name##ProxyWithInternal(rtc::Thread* primary_thread, \ 218*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<INTERNAL_CLASS> c) \ 219*d9f75844SAndroid Build Coastguard Worker : primary_thread_(primary_thread), c_(std::move(c)) {} \ 220*d9f75844SAndroid Build Coastguard Worker \ 221*d9f75844SAndroid Build Coastguard Worker private: \ 222*d9f75844SAndroid Build Coastguard Worker mutable rtc::Thread* primary_thread_; 223*d9f75844SAndroid Build Coastguard Worker 224*d9f75844SAndroid Build Coastguard Worker #define SECONDARY_PROXY_MAP_BOILERPLATE(class_name) \ 225*d9f75844SAndroid Build Coastguard Worker protected: \ 226*d9f75844SAndroid Build Coastguard Worker class_name##ProxyWithInternal(rtc::Thread* primary_thread, \ 227*d9f75844SAndroid Build Coastguard Worker rtc::Thread* secondary_thread, \ 228*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<INTERNAL_CLASS> c) \ 229*d9f75844SAndroid Build Coastguard Worker : primary_thread_(primary_thread), \ 230*d9f75844SAndroid Build Coastguard Worker secondary_thread_(secondary_thread), \ 231*d9f75844SAndroid Build Coastguard Worker c_(std::move(c)) {} \ 232*d9f75844SAndroid Build Coastguard Worker \ 233*d9f75844SAndroid Build Coastguard Worker private: \ 234*d9f75844SAndroid Build Coastguard Worker mutable rtc::Thread* primary_thread_; \ 235*d9f75844SAndroid Build Coastguard Worker mutable rtc::Thread* secondary_thread_; 236*d9f75844SAndroid Build Coastguard Worker 237*d9f75844SAndroid Build Coastguard Worker // Note that the destructor is protected so that the proxy can only be 238*d9f75844SAndroid Build Coastguard Worker // destroyed via RefCountInterface. 239*d9f75844SAndroid Build Coastguard Worker #define REFCOUNTED_PROXY_MAP_BOILERPLATE(class_name) \ 240*d9f75844SAndroid Build Coastguard Worker protected: \ 241*d9f75844SAndroid Build Coastguard Worker ~class_name##ProxyWithInternal() { \ 242*d9f75844SAndroid Build Coastguard Worker MethodCall<class_name##ProxyWithInternal, void> call( \ 243*d9f75844SAndroid Build Coastguard Worker this, &class_name##ProxyWithInternal::DestroyInternal); \ 244*d9f75844SAndroid Build Coastguard Worker call.Marshal(destructor_thread()); \ 245*d9f75844SAndroid Build Coastguard Worker } \ 246*d9f75844SAndroid Build Coastguard Worker \ 247*d9f75844SAndroid Build Coastguard Worker private: \ 248*d9f75844SAndroid Build Coastguard Worker const INTERNAL_CLASS* c() const { return c_.get(); } \ 249*d9f75844SAndroid Build Coastguard Worker INTERNAL_CLASS* c() { return c_.get(); } \ 250*d9f75844SAndroid Build Coastguard Worker void DestroyInternal() { c_ = nullptr; } \ 251*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<INTERNAL_CLASS> c_; 252*d9f75844SAndroid Build Coastguard Worker 253*d9f75844SAndroid Build Coastguard Worker // Note: This doesn't use a unique_ptr, because it intends to handle a corner 254*d9f75844SAndroid Build Coastguard Worker // case where an object's deletion triggers a callback that calls back into 255*d9f75844SAndroid Build Coastguard Worker // this proxy object. If relying on a unique_ptr to delete the object, its 256*d9f75844SAndroid Build Coastguard Worker // inner pointer would be set to null before this reentrant callback would have 257*d9f75844SAndroid Build Coastguard Worker // a chance to run, resulting in a segfault. 258*d9f75844SAndroid Build Coastguard Worker #define OWNED_PROXY_MAP_BOILERPLATE(class_name) \ 259*d9f75844SAndroid Build Coastguard Worker public: \ 260*d9f75844SAndroid Build Coastguard Worker ~class_name##ProxyWithInternal() { \ 261*d9f75844SAndroid Build Coastguard Worker MethodCall<class_name##ProxyWithInternal, void> call( \ 262*d9f75844SAndroid Build Coastguard Worker this, &class_name##ProxyWithInternal::DestroyInternal); \ 263*d9f75844SAndroid Build Coastguard Worker call.Marshal(destructor_thread()); \ 264*d9f75844SAndroid Build Coastguard Worker } \ 265*d9f75844SAndroid Build Coastguard Worker \ 266*d9f75844SAndroid Build Coastguard Worker private: \ 267*d9f75844SAndroid Build Coastguard Worker const INTERNAL_CLASS* c() const { return c_; } \ 268*d9f75844SAndroid Build Coastguard Worker INTERNAL_CLASS* c() { return c_; } \ 269*d9f75844SAndroid Build Coastguard Worker void DestroyInternal() { delete c_; } \ 270*d9f75844SAndroid Build Coastguard Worker INTERNAL_CLASS* c_; 271*d9f75844SAndroid Build Coastguard Worker 272*d9f75844SAndroid Build Coastguard Worker #define BEGIN_PRIMARY_PROXY_MAP(class_name) \ 273*d9f75844SAndroid Build Coastguard Worker PROXY_MAP_BOILERPLATE(class_name) \ 274*d9f75844SAndroid Build Coastguard Worker PRIMARY_PROXY_MAP_BOILERPLATE(class_name) \ 275*d9f75844SAndroid Build Coastguard Worker REFCOUNTED_PROXY_MAP_BOILERPLATE(class_name) \ 276*d9f75844SAndroid Build Coastguard Worker public: \ 277*d9f75844SAndroid Build Coastguard Worker static rtc::scoped_refptr<class_name##ProxyWithInternal> Create( \ 278*d9f75844SAndroid Build Coastguard Worker rtc::Thread* primary_thread, rtc::scoped_refptr<INTERNAL_CLASS> c) { \ 279*d9f75844SAndroid Build Coastguard Worker return rtc::make_ref_counted<class_name##ProxyWithInternal>( \ 280*d9f75844SAndroid Build Coastguard Worker primary_thread, std::move(c)); \ 281*d9f75844SAndroid Build Coastguard Worker } 282*d9f75844SAndroid Build Coastguard Worker 283*d9f75844SAndroid Build Coastguard Worker #define BEGIN_PROXY_MAP(class_name) \ 284*d9f75844SAndroid Build Coastguard Worker PROXY_MAP_BOILERPLATE(class_name) \ 285*d9f75844SAndroid Build Coastguard Worker SECONDARY_PROXY_MAP_BOILERPLATE(class_name) \ 286*d9f75844SAndroid Build Coastguard Worker REFCOUNTED_PROXY_MAP_BOILERPLATE(class_name) \ 287*d9f75844SAndroid Build Coastguard Worker public: \ 288*d9f75844SAndroid Build Coastguard Worker static rtc::scoped_refptr<class_name##ProxyWithInternal> Create( \ 289*d9f75844SAndroid Build Coastguard Worker rtc::Thread* primary_thread, rtc::Thread* secondary_thread, \ 290*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<INTERNAL_CLASS> c) { \ 291*d9f75844SAndroid Build Coastguard Worker return rtc::make_ref_counted<class_name##ProxyWithInternal>( \ 292*d9f75844SAndroid Build Coastguard Worker primary_thread, secondary_thread, std::move(c)); \ 293*d9f75844SAndroid Build Coastguard Worker } 294*d9f75844SAndroid Build Coastguard Worker 295*d9f75844SAndroid Build Coastguard Worker #define PROXY_PRIMARY_THREAD_DESTRUCTOR() \ 296*d9f75844SAndroid Build Coastguard Worker private: \ 297*d9f75844SAndroid Build Coastguard Worker rtc::Thread* destructor_thread() const { return primary_thread_; } \ 298*d9f75844SAndroid Build Coastguard Worker \ 299*d9f75844SAndroid Build Coastguard Worker public: // NOLINTNEXTLINE 300*d9f75844SAndroid Build Coastguard Worker 301*d9f75844SAndroid Build Coastguard Worker #define PROXY_SECONDARY_THREAD_DESTRUCTOR() \ 302*d9f75844SAndroid Build Coastguard Worker private: \ 303*d9f75844SAndroid Build Coastguard Worker rtc::Thread* destructor_thread() const { return secondary_thread_; } \ 304*d9f75844SAndroid Build Coastguard Worker \ 305*d9f75844SAndroid Build Coastguard Worker public: // NOLINTNEXTLINE 306*d9f75844SAndroid Build Coastguard Worker 307*d9f75844SAndroid Build Coastguard Worker #if defined(RTC_DISABLE_PROXY_TRACE_EVENTS) 308*d9f75844SAndroid Build Coastguard Worker #define TRACE_BOILERPLATE(method) \ 309*d9f75844SAndroid Build Coastguard Worker do { \ 310*d9f75844SAndroid Build Coastguard Worker } while (0) 311*d9f75844SAndroid Build Coastguard Worker #else // if defined(RTC_DISABLE_PROXY_TRACE_EVENTS) 312*d9f75844SAndroid Build Coastguard Worker #define TRACE_BOILERPLATE(method) \ 313*d9f75844SAndroid Build Coastguard Worker static constexpr auto class_and_method_name = \ 314*d9f75844SAndroid Build Coastguard Worker rtc::MakeCompileTimeString(proxy_name_) \ 315*d9f75844SAndroid Build Coastguard Worker .Concat(rtc::MakeCompileTimeString("::")) \ 316*d9f75844SAndroid Build Coastguard Worker .Concat(rtc::MakeCompileTimeString(#method)); \ 317*d9f75844SAndroid Build Coastguard Worker proxy_internal::ScopedTrace scoped_trace(class_and_method_name.string) 318*d9f75844SAndroid Build Coastguard Worker 319*d9f75844SAndroid Build Coastguard Worker #endif // if defined(RTC_DISABLE_PROXY_TRACE_EVENTS) 320*d9f75844SAndroid Build Coastguard Worker 321*d9f75844SAndroid Build Coastguard Worker #define PROXY_METHOD0(r, method) \ 322*d9f75844SAndroid Build Coastguard Worker r method() override { \ 323*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 324*d9f75844SAndroid Build Coastguard Worker MethodCall<C, r> call(c(), &C::method); \ 325*d9f75844SAndroid Build Coastguard Worker return call.Marshal(primary_thread_); \ 326*d9f75844SAndroid Build Coastguard Worker } 327*d9f75844SAndroid Build Coastguard Worker 328*d9f75844SAndroid Build Coastguard Worker #define PROXY_CONSTMETHOD0(r, method) \ 329*d9f75844SAndroid Build Coastguard Worker r method() const override { \ 330*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 331*d9f75844SAndroid Build Coastguard Worker ConstMethodCall<C, r> call(c(), &C::method); \ 332*d9f75844SAndroid Build Coastguard Worker return call.Marshal(primary_thread_); \ 333*d9f75844SAndroid Build Coastguard Worker } 334*d9f75844SAndroid Build Coastguard Worker 335*d9f75844SAndroid Build Coastguard Worker #define PROXY_METHOD1(r, method, t1) \ 336*d9f75844SAndroid Build Coastguard Worker r method(t1 a1) override { \ 337*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 338*d9f75844SAndroid Build Coastguard Worker MethodCall<C, r, t1> call(c(), &C::method, std::move(a1)); \ 339*d9f75844SAndroid Build Coastguard Worker return call.Marshal(primary_thread_); \ 340*d9f75844SAndroid Build Coastguard Worker } 341*d9f75844SAndroid Build Coastguard Worker 342*d9f75844SAndroid Build Coastguard Worker #define PROXY_CONSTMETHOD1(r, method, t1) \ 343*d9f75844SAndroid Build Coastguard Worker r method(t1 a1) const override { \ 344*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 345*d9f75844SAndroid Build Coastguard Worker ConstMethodCall<C, r, t1> call(c(), &C::method, std::move(a1)); \ 346*d9f75844SAndroid Build Coastguard Worker return call.Marshal(primary_thread_); \ 347*d9f75844SAndroid Build Coastguard Worker } 348*d9f75844SAndroid Build Coastguard Worker 349*d9f75844SAndroid Build Coastguard Worker #define PROXY_METHOD2(r, method, t1, t2) \ 350*d9f75844SAndroid Build Coastguard Worker r method(t1 a1, t2 a2) override { \ 351*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 352*d9f75844SAndroid Build Coastguard Worker MethodCall<C, r, t1, t2> call(c(), &C::method, std::move(a1), \ 353*d9f75844SAndroid Build Coastguard Worker std::move(a2)); \ 354*d9f75844SAndroid Build Coastguard Worker return call.Marshal(primary_thread_); \ 355*d9f75844SAndroid Build Coastguard Worker } 356*d9f75844SAndroid Build Coastguard Worker 357*d9f75844SAndroid Build Coastguard Worker #define PROXY_METHOD3(r, method, t1, t2, t3) \ 358*d9f75844SAndroid Build Coastguard Worker r method(t1 a1, t2 a2, t3 a3) override { \ 359*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 360*d9f75844SAndroid Build Coastguard Worker MethodCall<C, r, t1, t2, t3> call(c(), &C::method, std::move(a1), \ 361*d9f75844SAndroid Build Coastguard Worker std::move(a2), std::move(a3)); \ 362*d9f75844SAndroid Build Coastguard Worker return call.Marshal(primary_thread_); \ 363*d9f75844SAndroid Build Coastguard Worker } 364*d9f75844SAndroid Build Coastguard Worker 365*d9f75844SAndroid Build Coastguard Worker #define PROXY_METHOD4(r, method, t1, t2, t3, t4) \ 366*d9f75844SAndroid Build Coastguard Worker r method(t1 a1, t2 a2, t3 a3, t4 a4) override { \ 367*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 368*d9f75844SAndroid Build Coastguard Worker MethodCall<C, r, t1, t2, t3, t4> call(c(), &C::method, std::move(a1), \ 369*d9f75844SAndroid Build Coastguard Worker std::move(a2), std::move(a3), \ 370*d9f75844SAndroid Build Coastguard Worker std::move(a4)); \ 371*d9f75844SAndroid Build Coastguard Worker return call.Marshal(primary_thread_); \ 372*d9f75844SAndroid Build Coastguard Worker } 373*d9f75844SAndroid Build Coastguard Worker 374*d9f75844SAndroid Build Coastguard Worker #define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \ 375*d9f75844SAndroid Build Coastguard Worker r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \ 376*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 377*d9f75844SAndroid Build Coastguard Worker MethodCall<C, r, t1, t2, t3, t4, t5> call(c(), &C::method, std::move(a1), \ 378*d9f75844SAndroid Build Coastguard Worker std::move(a2), std::move(a3), \ 379*d9f75844SAndroid Build Coastguard Worker std::move(a4), std::move(a5)); \ 380*d9f75844SAndroid Build Coastguard Worker return call.Marshal(primary_thread_); \ 381*d9f75844SAndroid Build Coastguard Worker } 382*d9f75844SAndroid Build Coastguard Worker 383*d9f75844SAndroid Build Coastguard Worker // Define methods which should be invoked on the secondary thread. 384*d9f75844SAndroid Build Coastguard Worker #define PROXY_SECONDARY_METHOD0(r, method) \ 385*d9f75844SAndroid Build Coastguard Worker r method() override { \ 386*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 387*d9f75844SAndroid Build Coastguard Worker MethodCall<C, r> call(c(), &C::method); \ 388*d9f75844SAndroid Build Coastguard Worker return call.Marshal(secondary_thread_); \ 389*d9f75844SAndroid Build Coastguard Worker } 390*d9f75844SAndroid Build Coastguard Worker 391*d9f75844SAndroid Build Coastguard Worker #define PROXY_SECONDARY_CONSTMETHOD0(r, method) \ 392*d9f75844SAndroid Build Coastguard Worker r method() const override { \ 393*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 394*d9f75844SAndroid Build Coastguard Worker ConstMethodCall<C, r> call(c(), &C::method); \ 395*d9f75844SAndroid Build Coastguard Worker return call.Marshal(secondary_thread_); \ 396*d9f75844SAndroid Build Coastguard Worker } 397*d9f75844SAndroid Build Coastguard Worker 398*d9f75844SAndroid Build Coastguard Worker #define PROXY_SECONDARY_METHOD1(r, method, t1) \ 399*d9f75844SAndroid Build Coastguard Worker r method(t1 a1) override { \ 400*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 401*d9f75844SAndroid Build Coastguard Worker MethodCall<C, r, t1> call(c(), &C::method, std::move(a1)); \ 402*d9f75844SAndroid Build Coastguard Worker return call.Marshal(secondary_thread_); \ 403*d9f75844SAndroid Build Coastguard Worker } 404*d9f75844SAndroid Build Coastguard Worker 405*d9f75844SAndroid Build Coastguard Worker #define PROXY_SECONDARY_CONSTMETHOD1(r, method, t1) \ 406*d9f75844SAndroid Build Coastguard Worker r method(t1 a1) const override { \ 407*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 408*d9f75844SAndroid Build Coastguard Worker ConstMethodCall<C, r, t1> call(c(), &C::method, std::move(a1)); \ 409*d9f75844SAndroid Build Coastguard Worker return call.Marshal(secondary_thread_); \ 410*d9f75844SAndroid Build Coastguard Worker } 411*d9f75844SAndroid Build Coastguard Worker 412*d9f75844SAndroid Build Coastguard Worker #define PROXY_SECONDARY_METHOD2(r, method, t1, t2) \ 413*d9f75844SAndroid Build Coastguard Worker r method(t1 a1, t2 a2) override { \ 414*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 415*d9f75844SAndroid Build Coastguard Worker MethodCall<C, r, t1, t2> call(c(), &C::method, std::move(a1), \ 416*d9f75844SAndroid Build Coastguard Worker std::move(a2)); \ 417*d9f75844SAndroid Build Coastguard Worker return call.Marshal(secondary_thread_); \ 418*d9f75844SAndroid Build Coastguard Worker } 419*d9f75844SAndroid Build Coastguard Worker 420*d9f75844SAndroid Build Coastguard Worker #define PROXY_SECONDARY_CONSTMETHOD2(r, method, t1, t2) \ 421*d9f75844SAndroid Build Coastguard Worker r method(t1 a1, t2 a2) const override { \ 422*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 423*d9f75844SAndroid Build Coastguard Worker ConstMethodCall<C, r, t1, t2> call(c(), &C::method, std::move(a1), \ 424*d9f75844SAndroid Build Coastguard Worker std::move(a2)); \ 425*d9f75844SAndroid Build Coastguard Worker return call.Marshal(secondary_thread_); \ 426*d9f75844SAndroid Build Coastguard Worker } 427*d9f75844SAndroid Build Coastguard Worker 428*d9f75844SAndroid Build Coastguard Worker #define PROXY_SECONDARY_METHOD3(r, method, t1, t2, t3) \ 429*d9f75844SAndroid Build Coastguard Worker r method(t1 a1, t2 a2, t3 a3) override { \ 430*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 431*d9f75844SAndroid Build Coastguard Worker MethodCall<C, r, t1, t2, t3> call(c(), &C::method, std::move(a1), \ 432*d9f75844SAndroid Build Coastguard Worker std::move(a2), std::move(a3)); \ 433*d9f75844SAndroid Build Coastguard Worker return call.Marshal(secondary_thread_); \ 434*d9f75844SAndroid Build Coastguard Worker } 435*d9f75844SAndroid Build Coastguard Worker 436*d9f75844SAndroid Build Coastguard Worker #define PROXY_SECONDARY_CONSTMETHOD3(r, method, t1, t2) \ 437*d9f75844SAndroid Build Coastguard Worker r method(t1 a1, t2 a2, t3 a3) const override { \ 438*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 439*d9f75844SAndroid Build Coastguard Worker ConstMethodCall<C, r, t1, t2, t3> call(c(), &C::method, std::move(a1), \ 440*d9f75844SAndroid Build Coastguard Worker std::move(a2), std::move(a3)); \ 441*d9f75844SAndroid Build Coastguard Worker return call.Marshal(secondary_thread_); \ 442*d9f75844SAndroid Build Coastguard Worker } 443*d9f75844SAndroid Build Coastguard Worker 444*d9f75844SAndroid Build Coastguard Worker // For use when returning purely const state (set during construction). 445*d9f75844SAndroid Build Coastguard Worker // Use with caution. This method should only be used when the return value will 446*d9f75844SAndroid Build Coastguard Worker // always be the same. 447*d9f75844SAndroid Build Coastguard Worker #define BYPASS_PROXY_CONSTMETHOD0(r, method) \ 448*d9f75844SAndroid Build Coastguard Worker r method() const override { \ 449*d9f75844SAndroid Build Coastguard Worker TRACE_BOILERPLATE(method); \ 450*d9f75844SAndroid Build Coastguard Worker return c_->method(); \ 451*d9f75844SAndroid Build Coastguard Worker } 452*d9f75844SAndroid Build Coastguard Worker 453*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 454*d9f75844SAndroid Build Coastguard Worker 455*d9f75844SAndroid Build Coastguard Worker #endif // PC_PROXY_H_ 456