Chromium Code Reviews| Index: webrtc/base/thread_checker.h |
| diff --git a/webrtc/base/thread_checker.h b/webrtc/base/thread_checker.h |
| index 6cd7d7b9e0e83e7ef1194e933022dba7b3cbb1ba..a32f2c5cddd447677546716f9af24e660ee77235 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,74 @@ 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 |
| +class SCOPED_LOCKABLE AnnounceOnThread { |
| + public: |
| + template<typename ThreadLikeObject> |
| + explicit AnnounceOnThread(const ThreadLikeObject* thread_like_object) |
| + EXCLUSIVE_LOCK_FUNCTION(thread_like_object) {} |
| + |
| + 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(); |
| + } |
| + |
| + ~AnnounceOnThread() UNLOCK_FUNCTION() {} |
| + private: |
| + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AnnounceOnThread); |
| +}; |
| + |
| } // namespace rtc |
| +// RUN_ON/ACCESS_ON/RTC_DCHECK_RUN_ON macros allows to annotate variables are |
| +// access from same thread/queue. |
| +// Using tools designed to check mutexes, it checks at compile time everywhere |
| +// variable is access, there is a run-time dcheck thread/queue is correct. |
| +// |
| +// class Example { |
| +// rtc::TaskQueue* const encoder_queue_; |
| +// rtc::Thread* const network_thread_; |
| +// rtc::ThreadChecker pacer_thread_checker_; |
| +// |
| +// int var1_ ACCESS_ON(network_thread_); |
| +// Frame var2_ ACCESS_ON(encoder_queue_); |
| +// int var3_ ACCESS_ON(pacer_thread_checker_); |
| +// |
| +// void NeedVar1() { |
| +// RTC_DCHECK_RUN_ON(network_thread_); |
| +// var1_ = 42; |
| +// encoder_queue_->PostTask([this] { Encode(); }); |
|
tommi
2016/05/16 13:06:48
nit: I don't think we want to encourage using lamb
|
| +// } |
| +// |
| +// void Encode() { |
| +// RTC_DCHECK_RUN_ON(encoder_queue_); |
| +// DoSomething(var2_); |
| +// } |
| +// |
| +// int CalledFromPacer() RUN_ON(pacer_thread_checker_) { |
| +// return var3_; |
| +// } |
| +// |
| +// void CallMeFromPacer() { |
| +// RTC_DCHECK_RUN_ON(&pacer_thread_checker_) |
| +// << "Should be called from pacer"; |
| +// CalledFromPacer(); |
| +// } |
| +// } |
| + |
| +#define RTC_DCHECK_RUN_ON(thread_like_object) \ |
| + rtc::AnnounceOnThread thread_announcer(thread_like_object); \ |
| + RTC_DCHECK(rtc::AnnounceOnThread::IsCurrent(thread_like_object)) |
| + |
| #endif // WEBRTC_BASE_THREAD_CHECKER_H_ |