1 /* 2 * Copyright 2020 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 #ifndef RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H_ 11 #define RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H_ 12 13 #include <string> 14 #include <type_traits> 15 16 #include "api/task_queue/task_queue_base.h" 17 #include "rtc_base/platform_thread_types.h" 18 #include "rtc_base/synchronization/mutex.h" 19 #include "rtc_base/system/rtc_export.h" 20 #include "rtc_base/thread_annotations.h" 21 22 namespace webrtc { 23 namespace webrtc_sequence_checker_internal { 24 25 // Real implementation of SequenceChecker, for use in debug mode, or 26 // for temporary use in release mode (e.g. to RTC_CHECK on a threading issue 27 // seen only in the wild). 28 // 29 // Note: You should almost always use the SequenceChecker class to get the 30 // right version for your build configuration. 31 class RTC_EXPORT SequenceCheckerImpl { 32 public: 33 SequenceCheckerImpl(); 34 ~SequenceCheckerImpl() = default; 35 36 bool IsCurrent() const; 37 // Changes the task queue or thread that is checked for in IsCurrent. This can 38 // be useful when an object may be created on one task queue / thread and then 39 // used exclusively on another thread. 40 void Detach(); 41 42 // Returns a string that is formatted to match with the error string printed 43 // by RTC_CHECK() when a condition is not met. 44 // This is used in conjunction with the RTC_DCHECK_RUN_ON() macro. 45 std::string ExpectationToString() const; 46 47 private: 48 mutable Mutex lock_; 49 // These are mutable so that IsCurrent can set them. 50 mutable bool attached_ RTC_GUARDED_BY(lock_); 51 mutable rtc::PlatformThreadRef valid_thread_ RTC_GUARDED_BY(lock_); 52 mutable const TaskQueueBase* valid_queue_ RTC_GUARDED_BY(lock_); 53 mutable const void* valid_system_queue_ RTC_GUARDED_BY(lock_); 54 }; 55 56 // Do nothing implementation, for use in release mode. 57 // 58 // Note: You should almost always use the SequenceChecker class to get the 59 // right version for your build configuration. 60 class SequenceCheckerDoNothing { 61 public: IsCurrent()62 bool IsCurrent() const { return true; } Detach()63 void Detach() {} 64 }; 65 66 template <typename ThreadLikeObject> 67 std::enable_if_t<std::is_base_of_v<SequenceCheckerImpl, ThreadLikeObject>, 68 std::string> ExpectationToString(const ThreadLikeObject * checker)69ExpectationToString(const ThreadLikeObject* checker) { 70 #if RTC_DCHECK_IS_ON 71 return checker->ExpectationToString(); 72 #else 73 return std::string(); 74 #endif 75 } 76 77 // Catch-all implementation for types other than explicitly supported above. 78 template <typename ThreadLikeObject> 79 std::enable_if_t<!std::is_base_of_v<SequenceCheckerImpl, ThreadLikeObject>, 80 std::string> ExpectationToString(const ThreadLikeObject *)81ExpectationToString(const ThreadLikeObject*) { 82 return std::string(); 83 } 84 85 } // namespace webrtc_sequence_checker_internal 86 } // namespace webrtc 87 88 #endif // RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H_ 89