| Index: webrtc/base/thread_checker.h
|
| diff --git a/webrtc/base/thread_checker.h b/webrtc/base/thread_checker.h
|
| index 6cd7d7b9e0e83e7ef1194e933022dba7b3cbb1ba..265b2affcb7e15907ab4fce2167e1e73876cb7b5 100644
|
| --- a/webrtc/base/thread_checker.h
|
| +++ b/webrtc/base/thread_checker.h
|
| @@ -28,6 +28,9 @@
|
| #define ENABLE_THREAD_CHECKER 0
|
| #endif
|
|
|
| +#include "webrtc/base/checks.h"
|
| +#include "webrtc/base/constructormagic.h"
|
| +#include "webrtc/base/thread_annotations.h"
|
| #include "webrtc/base/thread_checker_impl.h"
|
|
|
| namespace rtc {
|
| @@ -77,15 +80,101 @@ class ThreadCheckerDoNothing {
|
| //
|
| // In Release mode, CalledOnValidThread will always return true.
|
| #if ENABLE_THREAD_CHECKER
|
| -class ThreadChecker : public ThreadCheckerImpl {
|
| +class LOCKABLE ThreadChecker : public ThreadCheckerImpl {
|
| };
|
| #else
|
| -class ThreadChecker : public ThreadCheckerDoNothing {
|
| +class LOCKABLE ThreadChecker : public ThreadCheckerDoNothing {
|
| };
|
| #endif // ENABLE_THREAD_CHECKER
|
|
|
| #undef ENABLE_THREAD_CHECKER
|
|
|
| +namespace internal {
|
| +class SCOPED_LOCKABLE AnnounceOnThread {
|
| + public:
|
| + template<typename ThreadLikeObject>
|
| + explicit AnnounceOnThread(const ThreadLikeObject* thread_like_object)
|
| + EXCLUSIVE_LOCK_FUNCTION(thread_like_object) {}
|
| + ~AnnounceOnThread() UNLOCK_FUNCTION() {}
|
| +
|
| + template<typename ThreadLikeObject>
|
| + static bool IsCurrent(const ThreadLikeObject* thread_like_object) {
|
| + return thread_like_object->IsCurrent();
|
| + }
|
| + static bool IsCurrent(const rtc::ThreadChecker* checker) {
|
| + return checker->CalledOnValidThread();
|
| + }
|
| +
|
| + private:
|
| + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AnnounceOnThread);
|
| +};
|
| +
|
| +} // namespace internal
|
| } // namespace rtc
|
|
|
| +// RUN_ON/ACCESS_ON/RTC_DCHECK_RUN_ON macros allows to annotate variables are
|
| +// accessed from same thread/task queue.
|
| +// Using tools designed to check mutexes, it checks at compile time everywhere
|
| +// variable is access, there is a run-time dcheck thread/task queue is correct.
|
| +//
|
| +// class ExampleThread {
|
| +// public:
|
| +// void NeedVar1() {
|
| +// RTC_DCHECK_RUN_ON(network_thread_);
|
| +// transport_->Send();
|
| +// }
|
| +//
|
| +// private:
|
| +// rtc::Thread* network_thread_;
|
| +// int transport_ ACCESS_ON(network_thread_);
|
| +// };
|
| +//
|
| +// class ExampleThreadChecker {
|
| +// public:
|
| +// int CalledFromPacer() RUN_ON(pacer_thread_checker_) {
|
| +// return var2_;
|
| +// }
|
| +//
|
| +// void CallMeFromPacer() {
|
| +// RTC_DCHECK_RUN_ON(&pacer_thread_checker_)
|
| +// << "Should be called from pacer";
|
| +// CalledFromPacer();
|
| +// }
|
| +//
|
| +// private:
|
| +// int pacer_var_ ACCESS_ON(pacer_thread_checker_);
|
| +// rtc::ThreadChecker pacer_thread_checker_;
|
| +// };
|
| +//
|
| +// class TaskQueueExample {
|
| +// public:
|
| +// class Encoder {
|
| +// public:
|
| +// rtc::TaskQueue* Queue() { return encoder_queue_; }
|
| +// void Encode() {
|
| +// RTC_DCHECK_RUN_ON(encoder_queue_);
|
| +// DoSomething(var_);
|
| +// }
|
| +//
|
| +// private:
|
| +// rtc::TaskQueue* const encoder_queue_;
|
| +// Frame var_ ACCESS_ON(encoder_queue_);
|
| +// };
|
| +//
|
| +// void Encode() {
|
| +// // Will fail at runtime when DCHECK is enabled:
|
| +// // encoder_->Encode();
|
| +// // Will work:
|
| +// rtc::scoped_ref_ptr<Encoder> encoder = encoder_;
|
| +// encoder_->Queue()->PostTask([encoder] { encoder->Encode(); });
|
| +// }
|
| +//
|
| +// private:
|
| +// rtc::scoped_ref_ptr<Encoder> encoder_;
|
| +// }
|
| +
|
| +#define RTC_DCHECK_RUN_ON(thread_like_object) \
|
| + rtc::internal::AnnounceOnThread thread_announcer(thread_like_object); \
|
| + RTC_DCHECK(rtc::internal::AnnounceOnThread::IsCurrent(thread_like_object))
|
| +
|
| #endif // WEBRTC_BASE_THREAD_CHECKER_H_
|
|
|