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_ |