1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_THREADING_THREAD_CHECKER_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_THREADING_THREAD_CHECKER_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <string_view> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 11*6777b538SAndroid Build Coastguard Worker #include "base/dcheck_is_on.h" 12*6777b538SAndroid Build Coastguard Worker #include "base/macros/uniquify.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/thread_annotations.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_checker_impl.h" 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker // ThreadChecker is a helper class used to help verify that some methods of a 17*6777b538SAndroid Build Coastguard Worker // class are called from the same thread (for thread-affinity). It supports 18*6777b538SAndroid Build Coastguard Worker // thread safety annotations (see base/thread_annotations.h). 19*6777b538SAndroid Build Coastguard Worker // 20*6777b538SAndroid Build Coastguard Worker // Use the macros below instead of the ThreadChecker directly so that the unused 21*6777b538SAndroid Build Coastguard Worker // member doesn't result in an extra byte (four when padded) per instance in 22*6777b538SAndroid Build Coastguard Worker // production. 23*6777b538SAndroid Build Coastguard Worker // 24*6777b538SAndroid Build Coastguard Worker // Usage of this class should be *rare* as most classes require thread-safety 25*6777b538SAndroid Build Coastguard Worker // but not thread-affinity. Prefer base::SequenceChecker to verify thread-safe 26*6777b538SAndroid Build Coastguard Worker // access. 27*6777b538SAndroid Build Coastguard Worker // 28*6777b538SAndroid Build Coastguard Worker // Thread-affinity checks should only be required in classes that use thread- 29*6777b538SAndroid Build Coastguard Worker // local-storage or a third-party API that does. 30*6777b538SAndroid Build Coastguard Worker // 31*6777b538SAndroid Build Coastguard Worker // Prefer to encode the minimum requirements of each class instead of the 32*6777b538SAndroid Build Coastguard Worker // environment it happens to run in today. e.g. if a class requires thread- 33*6777b538SAndroid Build Coastguard Worker // safety but not thread-affinity, use a SequenceChecker even if it happens to 34*6777b538SAndroid Build Coastguard Worker // run on a SingleThreadTaskRunner today. That makes it easier to understand 35*6777b538SAndroid Build Coastguard Worker // what would need to change to turn that SingleThreadTaskRunner into a 36*6777b538SAndroid Build Coastguard Worker // SequencedTaskRunner for ease of scheduling as well as minimizes side-effects 37*6777b538SAndroid Build Coastguard Worker // if that change is made. 38*6777b538SAndroid Build Coastguard Worker // 39*6777b538SAndroid Build Coastguard Worker // Debugging: 40*6777b538SAndroid Build Coastguard Worker // If ThreadChecker::EnableStackLogging() is called beforehand, then when 41*6777b538SAndroid Build Coastguard Worker // ThreadChecker fails, in addition to crashing with a stack trace of where 42*6777b538SAndroid Build Coastguard Worker // the violation occurred, it will also dump a stack trace of where the 43*6777b538SAndroid Build Coastguard Worker // checker was bound to a thread. 44*6777b538SAndroid Build Coastguard Worker // 45*6777b538SAndroid Build Coastguard Worker // Usage: 46*6777b538SAndroid Build Coastguard Worker // class MyClass { 47*6777b538SAndroid Build Coastguard Worker // public: 48*6777b538SAndroid Build Coastguard Worker // MyClass() { 49*6777b538SAndroid Build Coastguard Worker // // It's sometimes useful to detach on construction for objects that are 50*6777b538SAndroid Build Coastguard Worker // // constructed in one place and forever after used from another 51*6777b538SAndroid Build Coastguard Worker // // thread. 52*6777b538SAndroid Build Coastguard Worker // DETACH_FROM_THREAD(thread_checker_); 53*6777b538SAndroid Build Coastguard Worker // } 54*6777b538SAndroid Build Coastguard Worker // 55*6777b538SAndroid Build Coastguard Worker // ~MyClass() { 56*6777b538SAndroid Build Coastguard Worker // // ThreadChecker doesn't automatically check it's destroyed on origin 57*6777b538SAndroid Build Coastguard Worker // // thread for the same reason it's sometimes detached in the 58*6777b538SAndroid Build Coastguard Worker // // constructor. It's okay to destroy off thread if the owner otherwise 59*6777b538SAndroid Build Coastguard Worker // // knows usage on the associated thread is done. If you're not 60*6777b538SAndroid Build Coastguard Worker // // detaching in the constructor, you probably want to explicitly check 61*6777b538SAndroid Build Coastguard Worker // // in the destructor. 62*6777b538SAndroid Build Coastguard Worker // DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); 63*6777b538SAndroid Build Coastguard Worker // } 64*6777b538SAndroid Build Coastguard Worker // 65*6777b538SAndroid Build Coastguard Worker // void MyMethod() { 66*6777b538SAndroid Build Coastguard Worker // DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); 67*6777b538SAndroid Build Coastguard Worker // ... (do stuff) ... 68*6777b538SAndroid Build Coastguard Worker // } 69*6777b538SAndroid Build Coastguard Worker // 70*6777b538SAndroid Build Coastguard Worker // void MyOtherMethod() 71*6777b538SAndroid Build Coastguard Worker // VALID_CONTEXT_REQUIRED(thread_checker_) { 72*6777b538SAndroid Build Coastguard Worker // foo_ = 42; 73*6777b538SAndroid Build Coastguard Worker // } 74*6777b538SAndroid Build Coastguard Worker // 75*6777b538SAndroid Build Coastguard Worker // private: 76*6777b538SAndroid Build Coastguard Worker // int foo_ GUARDED_BY_CONTEXT(thread_checker_); 77*6777b538SAndroid Build Coastguard Worker // 78*6777b538SAndroid Build Coastguard Worker // THREAD_CHECKER(thread_checker_); 79*6777b538SAndroid Build Coastguard Worker // } 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 82*6777b538SAndroid Build Coastguard Worker #define THREAD_CHECKER(name) base::ThreadChecker name 83*6777b538SAndroid Build Coastguard Worker #define DCHECK_CALLED_ON_VALID_THREAD(name, ...) \ 84*6777b538SAndroid Build Coastguard Worker base::ScopedValidateThreadChecker BASE_UNIQUIFY( \ 85*6777b538SAndroid Build Coastguard Worker scoped_validate_thread_checker_)(name, ##__VA_ARGS__); 86*6777b538SAndroid Build Coastguard Worker #define DETACH_FROM_THREAD(name) (name).DetachFromThread() 87*6777b538SAndroid Build Coastguard Worker #else // DCHECK_IS_ON() 88*6777b538SAndroid Build Coastguard Worker #define THREAD_CHECKER(name) static_assert(true, "") 89*6777b538SAndroid Build Coastguard Worker #define DCHECK_CALLED_ON_VALID_THREAD(name, ...) EAT_CHECK_STREAM_PARAMS() 90*6777b538SAndroid Build Coastguard Worker #define DETACH_FROM_THREAD(name) 91*6777b538SAndroid Build Coastguard Worker #endif // DCHECK_IS_ON() 92*6777b538SAndroid Build Coastguard Worker 93*6777b538SAndroid Build Coastguard Worker namespace base { 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard Worker // Do nothing implementation, for use in release mode. 96*6777b538SAndroid Build Coastguard Worker // 97*6777b538SAndroid Build Coastguard Worker // Note: You should almost always use the ThreadChecker class (through the above 98*6777b538SAndroid Build Coastguard Worker // macros) to get the right version for your build configuration. 99*6777b538SAndroid Build Coastguard Worker // Note: This is only a check, not a "lock". It is marked "LOCKABLE" only in 100*6777b538SAndroid Build Coastguard Worker // order to support thread_annotations.h. 101*6777b538SAndroid Build Coastguard Worker class LOCKABLE ThreadCheckerDoNothing { 102*6777b538SAndroid Build Coastguard Worker public: EnableStackLogging()103*6777b538SAndroid Build Coastguard Worker static void EnableStackLogging() {} 104*6777b538SAndroid Build Coastguard Worker 105*6777b538SAndroid Build Coastguard Worker ThreadCheckerDoNothing() = default; 106*6777b538SAndroid Build Coastguard Worker 107*6777b538SAndroid Build Coastguard Worker ThreadCheckerDoNothing(const ThreadCheckerDoNothing&) = delete; 108*6777b538SAndroid Build Coastguard Worker ThreadCheckerDoNothing& operator=(const ThreadCheckerDoNothing&) = delete; 109*6777b538SAndroid Build Coastguard Worker 110*6777b538SAndroid Build Coastguard Worker // Moving between matching threads is allowed to help classes with 111*6777b538SAndroid Build Coastguard Worker // ThreadCheckers that want a default move-construct/assign. 112*6777b538SAndroid Build Coastguard Worker ThreadCheckerDoNothing(ThreadCheckerDoNothing&& other) = default; 113*6777b538SAndroid Build Coastguard Worker ThreadCheckerDoNothing& operator=(ThreadCheckerDoNothing&& other) = default; 114*6777b538SAndroid Build Coastguard Worker 115*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool CalledOnValidThread( 116*6777b538SAndroid Build Coastguard Worker std::unique_ptr<void*> = nullptr) const { 117*6777b538SAndroid Build Coastguard Worker return true; 118*6777b538SAndroid Build Coastguard Worker } DetachFromThread()119*6777b538SAndroid Build Coastguard Worker void DetachFromThread() {} 120*6777b538SAndroid Build Coastguard Worker }; 121*6777b538SAndroid Build Coastguard Worker 122*6777b538SAndroid Build Coastguard Worker // Note that ThreadCheckerImpl::CalledOnValidThread() returns false when called 123*6777b538SAndroid Build Coastguard Worker // from tasks posted to SingleThreadTaskRunners bound to different sequences, 124*6777b538SAndroid Build Coastguard Worker // even if the tasks happen to run on the same thread (e.g. two independent 125*6777b538SAndroid Build Coastguard Worker // SingleThreadTaskRunners on the ThreadPool that happen to share a thread). 126*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 127*6777b538SAndroid Build Coastguard Worker class ThreadChecker : public ThreadCheckerImpl { 128*6777b538SAndroid Build Coastguard Worker }; 129*6777b538SAndroid Build Coastguard Worker #else 130*6777b538SAndroid Build Coastguard Worker class ThreadChecker : public ThreadCheckerDoNothing { 131*6777b538SAndroid Build Coastguard Worker }; 132*6777b538SAndroid Build Coastguard Worker #endif // DCHECK_IS_ON() 133*6777b538SAndroid Build Coastguard Worker 134*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 135*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT SCOPED_LOCKABLE ScopedValidateThreadChecker { 136*6777b538SAndroid Build Coastguard Worker public: 137*6777b538SAndroid Build Coastguard Worker explicit ScopedValidateThreadChecker(const ThreadChecker& checker) 138*6777b538SAndroid Build Coastguard Worker EXCLUSIVE_LOCK_FUNCTION(checker); 139*6777b538SAndroid Build Coastguard Worker ScopedValidateThreadChecker(const ThreadChecker& checker, 140*6777b538SAndroid Build Coastguard Worker std::string_view msg) 141*6777b538SAndroid Build Coastguard Worker EXCLUSIVE_LOCK_FUNCTION(checker); 142*6777b538SAndroid Build Coastguard Worker 143*6777b538SAndroid Build Coastguard Worker ScopedValidateThreadChecker(const ScopedValidateThreadChecker&) = delete; 144*6777b538SAndroid Build Coastguard Worker ScopedValidateThreadChecker& operator=(const ScopedValidateThreadChecker&) = 145*6777b538SAndroid Build Coastguard Worker delete; 146*6777b538SAndroid Build Coastguard Worker 147*6777b538SAndroid Build Coastguard Worker ~ScopedValidateThreadChecker() UNLOCK_FUNCTION(); 148*6777b538SAndroid Build Coastguard Worker }; 149*6777b538SAndroid Build Coastguard Worker #endif 150*6777b538SAndroid Build Coastguard Worker 151*6777b538SAndroid Build Coastguard Worker } // namespace base 152*6777b538SAndroid Build Coastguard Worker 153*6777b538SAndroid Build Coastguard Worker #endif // BASE_THREADING_THREAD_CHECKER_H_ 154