xref: /aosp_15_r20/external/webrtc/rtc_base/synchronization/sequence_checker_internal.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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)69 ExpectationToString(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 *)81 ExpectationToString(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