OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... | |
21 // std::string FooC(bool arg1) = 0; | 21 // std::string FooC(bool arg1) = 0; |
22 // }; | 22 // }; |
23 // | 23 // |
24 // Note that return types can not be a const reference. | 24 // Note that return types can not be a const reference. |
25 // | 25 // |
26 // class Test : public TestInterface { | 26 // class Test : public TestInterface { |
27 // ... implementation of the interface. | 27 // ... implementation of the interface. |
28 // }; | 28 // }; |
29 // | 29 // |
30 // BEGIN_PROXY_MAP(Test) | 30 // BEGIN_PROXY_MAP(Test) |
31 // PROXY_SIGNALING_THREAD_DESTRUCTOR() | |
pthatcher1
2017/01/17 19:44:00
What happens if one doesn't include this line? Wo
Taylor Brandstetter
2017/01/18 01:17:14
You'd get a compile error: "use of undeclared iden
| |
31 // PROXY_METHOD0(std::string, FooA) | 32 // PROXY_METHOD0(std::string, FooA) |
32 // PROXY_CONSTMETHOD1(std::string, FooB, arg1) | 33 // PROXY_CONSTMETHOD1(std::string, FooB, arg1) |
33 // PROXY_WORKER_METHOD1(std::string, FooC, arg1) | 34 // PROXY_WORKER_METHOD1(std::string, FooC, arg1) |
34 // END_PROXY() | 35 // END_PROXY_MAP() |
35 // | 36 // |
36 // where the first two methods are invoked on the signaling thread, | 37 // Where the destructor and first two methods are invoked on the signaling |
37 // and the third is invoked on the worker thread. | 38 // thread, and the third is invoked on the worker thread. |
38 // | 39 // |
39 // The proxy can be created using | 40 // The proxy can be created using |
40 // | 41 // |
41 // TestProxy::Create(Thread* signaling_thread, Thread* worker_thread, | 42 // TestProxy::Create(Thread* signaling_thread, Thread* worker_thread, |
42 // TestInterface*). | 43 // TestInterface*). |
43 // | 44 // |
44 // The variant defined with BEGIN_SIGNALING_PROXY_MAP is unaware of | 45 // The variant defined with BEGIN_SIGNALING_PROXY_MAP is unaware of |
45 // the worker thread, and invokes all methods on the signaling thread. | 46 // the worker thread, and invokes all methods on the signaling thread. |
47 // | |
48 // The variant defined with BEGIN_NON_REFCOUNTED_PROXY_MAP does not use | |
pthatcher1
2017/01/17 19:44:00
Would BEGIN_OWNED_PROXY_MAP be a better name?
Taylor Brandstetter
2017/01/18 01:17:14
Done.
| |
49 // refcounting, and instead just takes ownership of the object being proxied. | |
46 | 50 |
47 #ifndef WEBRTC_API_PROXY_H_ | 51 #ifndef WEBRTC_API_PROXY_H_ |
48 #define WEBRTC_API_PROXY_H_ | 52 #define WEBRTC_API_PROXY_H_ |
49 | 53 |
50 #include <memory> | 54 #include <memory> |
51 | 55 |
52 #include "webrtc/base/event.h" | 56 #include "webrtc/base/event.h" |
53 #include "webrtc/base/thread.h" | 57 #include "webrtc/base/thread.h" |
54 | 58 |
55 namespace webrtc { | 59 namespace webrtc { |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
299 C* c_; | 303 C* c_; |
300 Method m_; | 304 Method m_; |
301 ReturnType<R> r_; | 305 ReturnType<R> r_; |
302 T1 a1_; | 306 T1 a1_; |
303 T2 a2_; | 307 T2 a2_; |
304 T3 a3_; | 308 T3 a3_; |
305 T4 a4_; | 309 T4 a4_; |
306 T5 a5_; | 310 T5 a5_; |
307 }; | 311 }; |
308 | 312 |
309 #define BEGIN_SIGNALING_PROXY_MAP(c) \ | 313 // Helper macros to reduce code duplication. |
310 template <class INTERNAL_CLASS> \ | 314 #define PROXY_MAP_BOILERPLATE(c) \ |
311 class c##ProxyWithInternal; \ | |
312 typedef c##ProxyWithInternal<c##Interface> c##Proxy; \ | |
313 template <class INTERNAL_CLASS> \ | |
314 class c##ProxyWithInternal : public c##Interface { \ | |
315 protected: \ | |
316 typedef c##Interface C; \ | |
317 c##ProxyWithInternal(rtc::Thread* signaling_thread, INTERNAL_CLASS* c) \ | |
318 : signaling_thread_(signaling_thread), c_(c) {} \ | |
319 ~c##ProxyWithInternal() { \ | |
320 MethodCall0<c##ProxyWithInternal, void> call( \ | |
321 this, &c##ProxyWithInternal::Release_s); \ | |
322 call.Marshal(RTC_FROM_HERE, signaling_thread_); \ | |
323 } \ | |
324 \ | |
325 public: \ | |
326 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \ | |
327 rtc::Thread* signaling_thread, \ | |
328 INTERNAL_CLASS* c) { \ | |
329 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \ | |
330 c); \ | |
331 } \ | |
332 const INTERNAL_CLASS* internal() const { return c_.get(); } \ | |
333 INTERNAL_CLASS* internal() { return c_.get(); } | |
334 | |
335 #define BEGIN_PROXY_MAP(c) \ | |
336 template <class INTERNAL_CLASS> \ | 315 template <class INTERNAL_CLASS> \ |
337 class c##ProxyWithInternal; \ | 316 class c##ProxyWithInternal; \ |
338 typedef c##ProxyWithInternal<c##Interface> c##Proxy; \ | 317 typedef c##ProxyWithInternal<c##Interface> c##Proxy; \ |
339 template <class INTERNAL_CLASS> \ | 318 template <class INTERNAL_CLASS> \ |
340 class c##ProxyWithInternal : public c##Interface { \ | 319 class c##ProxyWithInternal : public c##Interface { \ |
341 protected: \ | 320 protected: \ |
342 typedef c##Interface C; \ | 321 typedef c##Interface C; \ |
343 c##ProxyWithInternal(rtc::Thread* signaling_thread, \ | |
344 rtc::Thread* worker_thread, \ | |
345 INTERNAL_CLASS* c) \ | |
346 : signaling_thread_(signaling_thread), \ | |
347 worker_thread_(worker_thread), \ | |
348 c_(c) {} \ | |
349 ~c##ProxyWithInternal() { \ | |
350 MethodCall0<c##ProxyWithInternal, void> call( \ | |
351 this, &c##ProxyWithInternal::Release_s); \ | |
352 call.Marshal(RTC_FROM_HERE, signaling_thread_); \ | |
353 } \ | |
354 \ | 322 \ |
355 public: \ | 323 public: \ |
356 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \ | |
357 rtc::Thread* signaling_thread, \ | |
358 rtc::Thread* worker_thread, \ | |
359 INTERNAL_CLASS* c) { \ | |
360 return new rtc::RefCountedObject<c##ProxyWithInternal>( \ | |
361 signaling_thread, worker_thread, c); \ | |
362 } \ | |
363 const INTERNAL_CLASS* internal() const { return c_.get(); } \ | 324 const INTERNAL_CLASS* internal() const { return c_.get(); } \ |
364 INTERNAL_CLASS* internal() { return c_.get(); } | 325 INTERNAL_CLASS* internal() { return c_.get(); } |
365 | 326 |
327 #define SIGNALING_PROXY_MAP_BOILERPLATE(c) \ | |
328 protected: \ | |
329 c##ProxyWithInternal(rtc::Thread* signaling_thread, INTERNAL_CLASS* c) \ | |
330 : signaling_thread_(signaling_thread), c_(c) {} \ | |
331 \ | |
332 private: \ | |
333 mutable rtc::Thread* signaling_thread_; | |
334 | |
335 #define WORKER_PROXY_MAP_BOILERPLATE(c) \ | |
336 protected: \ | |
337 c##ProxyWithInternal(rtc::Thread* signaling_thread, \ | |
338 rtc::Thread* worker_thread, INTERNAL_CLASS* c) \ | |
339 : signaling_thread_(signaling_thread), \ | |
340 worker_thread_(worker_thread), \ | |
341 c_(c) {} \ | |
342 \ | |
343 private: \ | |
344 mutable rtc::Thread* signaling_thread_; \ | |
345 mutable rtc::Thread* worker_thread_; | |
346 | |
347 // Note that the destructor is protected so that the proxy can only be | |
348 // destroyed via RefCountInterface. | |
349 #define REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \ | |
350 protected: \ | |
351 ~c##ProxyWithInternal() { \ | |
352 MethodCall0<c##ProxyWithInternal, void> call( \ | |
353 this, &c##ProxyWithInternal::DestroyInternal); \ | |
354 call.Marshal(RTC_FROM_HERE, destructor_thread()); \ | |
355 } \ | |
356 \ | |
357 private: \ | |
358 void DestroyInternal() { c_ = nullptr; } \ | |
359 rtc::scoped_refptr<INTERNAL_CLASS> c_; | |
360 | |
361 #define NON_REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \ | |
362 public: \ | |
363 ~c##ProxyWithInternal() { \ | |
364 MethodCall0<c##ProxyWithInternal, void> call( \ | |
365 this, &c##ProxyWithInternal::DestroyInternal); \ | |
366 call.Marshal(RTC_FROM_HERE, destructor_thread()); \ | |
367 } \ | |
368 \ | |
369 private: \ | |
370 void DestroyInternal() { c_.reset(nullptr); } \ | |
371 std::unique_ptr<INTERNAL_CLASS> c_; | |
372 | |
373 #define BEGIN_SIGNALING_PROXY_MAP(c) \ | |
374 PROXY_MAP_BOILERPLATE(c) \ | |
375 SIGNALING_PROXY_MAP_BOILERPLATE(c) \ | |
376 REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \ | |
377 public: \ | |
378 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \ | |
379 rtc::Thread* signaling_thread, INTERNAL_CLASS* c) { \ | |
380 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \ | |
381 c); \ | |
382 } | |
383 | |
384 #define BEGIN_PROXY_MAP(c) \ | |
385 PROXY_MAP_BOILERPLATE(c) \ | |
386 WORKER_PROXY_MAP_BOILERPLATE(c) \ | |
387 REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \ | |
388 public: \ | |
389 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \ | |
390 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, \ | |
391 INTERNAL_CLASS* c) { \ | |
392 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \ | |
393 worker_thread, c); \ | |
394 } | |
395 | |
396 #define BEGIN_NON_REFCOUNTED_PROXY_MAP(c) \ | |
397 PROXY_MAP_BOILERPLATE(c) \ | |
398 WORKER_PROXY_MAP_BOILERPLATE(c) \ | |
399 NON_REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \ | |
400 public: \ | |
401 static std::unique_ptr<c##ProxyWithInternal> Create( \ | |
402 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, \ | |
403 INTERNAL_CLASS* c) { \ | |
404 return std::unique_ptr<c##ProxyWithInternal>( \ | |
405 new c##ProxyWithInternal(signaling_thread, worker_thread, c)); \ | |
406 } | |
407 | |
408 #define PROXY_SIGNALING_THREAD_DESTRUCTOR() \ | |
409 private: \ | |
410 rtc::Thread* destructor_thread() const { return signaling_thread_; } \ | |
411 \ | |
412 public: | |
413 | |
414 #define PROXY_WORKER_THREAD_DESTRUCTOR() \ | |
415 private: \ | |
416 rtc::Thread* destructor_thread() const { return worker_thread_; } \ | |
417 \ | |
418 public: | |
419 | |
366 #define PROXY_METHOD0(r, method) \ | 420 #define PROXY_METHOD0(r, method) \ |
367 r method() override { \ | 421 r method() override { \ |
368 MethodCall0<C, r> call(c_.get(), &C::method); \ | 422 MethodCall0<C, r> call(c_.get(), &C::method); \ |
369 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \ | 423 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \ |
370 } | 424 } |
371 | 425 |
372 #define PROXY_CONSTMETHOD0(r, method) \ | 426 #define PROXY_CONSTMETHOD0(r, method) \ |
373 r method() const override { \ | 427 r method() const override { \ |
374 ConstMethodCall0<C, r> call(c_.get(), &C::method); \ | 428 ConstMethodCall0<C, r> call(c_.get(), &C::method); \ |
375 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \ | 429 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \ |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
407 } | 461 } |
408 | 462 |
409 #define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \ | 463 #define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \ |
410 r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \ | 464 r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \ |
411 MethodCall5<C, r, t1, t2, t3, t4, t5> call(c_.get(), &C::method, a1, a2, \ | 465 MethodCall5<C, r, t1, t2, t3, t4, t5> call(c_.get(), &C::method, a1, a2, \ |
412 a3, a4, a5); \ | 466 a3, a4, a5); \ |
413 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \ | 467 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \ |
414 } | 468 } |
415 | 469 |
416 // Define methods which should be invoked on the worker thread. | 470 // Define methods which should be invoked on the worker thread. |
471 #define PROXY_WORKER_METHOD0(r, method) \ | |
472 r method() override { \ | |
473 MethodCall0<C, r> call(c_.get(), &C::method); \ | |
474 return call.Marshal(RTC_FROM_HERE, worker_thread_); \ | |
475 } | |
476 | |
477 #define PROXY_WORKER_CONSTMETHOD0(r, method) \ | |
478 r method() const override { \ | |
479 ConstMethodCall0<C, r> call(c_.get(), &C::method); \ | |
480 return call.Marshal(RTC_FROM_HERE, worker_thread_); \ | |
481 } | |
482 | |
417 #define PROXY_WORKER_METHOD1(r, method, t1) \ | 483 #define PROXY_WORKER_METHOD1(r, method, t1) \ |
418 r method(t1 a1) override { \ | 484 r method(t1 a1) override { \ |
419 MethodCall1<C, r, t1> call(c_.get(), &C::method, a1); \ | 485 MethodCall1<C, r, t1> call(c_.get(), &C::method, a1); \ |
420 return call.Marshal(RTC_FROM_HERE, worker_thread_); \ | 486 return call.Marshal(RTC_FROM_HERE, worker_thread_); \ |
421 } | 487 } |
422 | 488 |
489 #define PROXY_WORKER_CONSTMETHOD1(r, method, t1) \ | |
490 r method(t1 a1) const override { \ | |
491 ConstMethodCall1<C, r, t1> call(c_.get(), &C::method, a1); \ | |
492 return call.Marshal(RTC_FROM_HERE, worker_thread_); \ | |
493 } | |
494 | |
423 #define PROXY_WORKER_METHOD2(r, method, t1, t2) \ | 495 #define PROXY_WORKER_METHOD2(r, method, t1, t2) \ |
424 r method(t1 a1, t2 a2) override { \ | 496 r method(t1 a1, t2 a2) override { \ |
425 MethodCall2<C, r, t1, t2> call(c_.get(), &C::method, a1, a2); \ | 497 MethodCall2<C, r, t1, t2> call(c_.get(), &C::method, a1, a2); \ |
426 return call.Marshal(RTC_FROM_HERE, worker_thread_); \ | 498 return call.Marshal(RTC_FROM_HERE, worker_thread_); \ |
427 } | 499 } |
428 | 500 |
429 #define END_SIGNALING_PROXY() \ | 501 #define PROXY_WORKER_CONSTMETHOD2(r, method, t1, t2) \ |
430 private: \ | 502 r method(t1 a1, t2 a2) const override { \ |
431 void Release_s() { c_ = NULL; } \ | 503 ConstMethodCall2<C, r, t1, t2> call(c_.get(), &C::method, a1, a2); \ |
432 mutable rtc::Thread* signaling_thread_; \ | 504 return call.Marshal(RTC_FROM_HERE, worker_thread_); \ |
433 rtc::scoped_refptr<INTERNAL_CLASS> c_; \ | 505 } |
434 } \ | |
435 ; | |
436 | 506 |
437 #define END_PROXY() \ | 507 #define END_PROXY_MAP() \ |
438 private: \ | 508 } \ |
439 void Release_s() { c_ = NULL; } \ | |
440 mutable rtc::Thread* signaling_thread_; \ | |
441 mutable rtc::Thread* worker_thread_; \ | |
442 rtc::scoped_refptr<INTERNAL_CLASS> c_; \ | |
443 } \ | |
444 ; | 509 ; |
445 | 510 |
446 } // namespace webrtc | 511 } // namespace webrtc |
447 | 512 |
448 #endif // WEBRTC_API_PROXY_H_ | 513 #endif // WEBRTC_API_PROXY_H_ |
OLD | NEW |