1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_THREADING_THREAD_CHECKER_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_THREADING_THREAD_CHECKER_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include "base/compiler_specific.h" 9*635a8641SAndroid Build Coastguard Worker #include "base/logging.h" 10*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_checker_impl.h" 11*635a8641SAndroid Build Coastguard Worker 12*635a8641SAndroid Build Coastguard Worker // ThreadChecker is a helper class used to help verify that some methods of a 13*635a8641SAndroid Build Coastguard Worker // class are called from the same thread (for thread-affinity). 14*635a8641SAndroid Build Coastguard Worker // 15*635a8641SAndroid Build Coastguard Worker // Use the macros below instead of the ThreadChecker directly so that the unused 16*635a8641SAndroid Build Coastguard Worker // member doesn't result in an extra byte (four when padded) per instance in 17*635a8641SAndroid Build Coastguard Worker // production. 18*635a8641SAndroid Build Coastguard Worker // 19*635a8641SAndroid Build Coastguard Worker // Usage of this class should be *rare* as most classes require thread-safety 20*635a8641SAndroid Build Coastguard Worker // but not thread-affinity. Prefer base::SequenceChecker to verify thread-safe 21*635a8641SAndroid Build Coastguard Worker // access. 22*635a8641SAndroid Build Coastguard Worker // 23*635a8641SAndroid Build Coastguard Worker // Thread-affinity checks should only be required in classes that use thread- 24*635a8641SAndroid Build Coastguard Worker // local-storage or a third-party API that does. 25*635a8641SAndroid Build Coastguard Worker // 26*635a8641SAndroid Build Coastguard Worker // Prefer to encode the minimum requirements of each class instead of the 27*635a8641SAndroid Build Coastguard Worker // environment it happens to run in today. e.g. if a class requires thread- 28*635a8641SAndroid Build Coastguard Worker // safety but not thread-affinity, use a SequenceChecker even if it happens to 29*635a8641SAndroid Build Coastguard Worker // run on a SingleThreadTaskRunner today. That makes it easier to understand 30*635a8641SAndroid Build Coastguard Worker // what would need to change to turn that SingleThreadTaskRunner into a 31*635a8641SAndroid Build Coastguard Worker // SequencedTaskRunner for ease of scheduling as well as minimizes side-effects 32*635a8641SAndroid Build Coastguard Worker // if that change is made. 33*635a8641SAndroid Build Coastguard Worker // 34*635a8641SAndroid Build Coastguard Worker // Usage: 35*635a8641SAndroid Build Coastguard Worker // class MyClass { 36*635a8641SAndroid Build Coastguard Worker // public: 37*635a8641SAndroid Build Coastguard Worker // MyClass() { 38*635a8641SAndroid Build Coastguard Worker // // It's sometimes useful to detach on construction for objects that are 39*635a8641SAndroid Build Coastguard Worker // // constructed in one place and forever after used from another 40*635a8641SAndroid Build Coastguard Worker // // thread. 41*635a8641SAndroid Build Coastguard Worker // DETACH_FROM_THREAD(my_thread_checker_); 42*635a8641SAndroid Build Coastguard Worker // } 43*635a8641SAndroid Build Coastguard Worker // 44*635a8641SAndroid Build Coastguard Worker // ~MyClass() { 45*635a8641SAndroid Build Coastguard Worker // // ThreadChecker doesn't automatically check it's destroyed on origin 46*635a8641SAndroid Build Coastguard Worker // // thread for the same reason it's sometimes detached in the 47*635a8641SAndroid Build Coastguard Worker // // constructor. It's okay to destroy off thread if the owner otherwise 48*635a8641SAndroid Build Coastguard Worker // // knows usage on the associated thread is done. If you're not 49*635a8641SAndroid Build Coastguard Worker // // detaching in the constructor, you probably want to explicitly check 50*635a8641SAndroid Build Coastguard Worker // // in the destructor. 51*635a8641SAndroid Build Coastguard Worker // DCHECK_CALLED_ON_VALID_THREAD(my_thread_checker_); 52*635a8641SAndroid Build Coastguard Worker // } 53*635a8641SAndroid Build Coastguard Worker // 54*635a8641SAndroid Build Coastguard Worker // void MyMethod() { 55*635a8641SAndroid Build Coastguard Worker // DCHECK_CALLED_ON_VALID_THREAD(my_thread_checker_); 56*635a8641SAndroid Build Coastguard Worker // ... (do stuff) ... 57*635a8641SAndroid Build Coastguard Worker // } 58*635a8641SAndroid Build Coastguard Worker // 59*635a8641SAndroid Build Coastguard Worker // private: 60*635a8641SAndroid Build Coastguard Worker // THREAD_CHECKER(my_thread_checker_); 61*635a8641SAndroid Build Coastguard Worker // } 62*635a8641SAndroid Build Coastguard Worker 63*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 64*635a8641SAndroid Build Coastguard Worker #define THREAD_CHECKER(name) base::ThreadChecker name 65*635a8641SAndroid Build Coastguard Worker #define DCHECK_CALLED_ON_VALID_THREAD(name) DCHECK((name).CalledOnValidThread()) 66*635a8641SAndroid Build Coastguard Worker #define DETACH_FROM_THREAD(name) (name).DetachFromThread() 67*635a8641SAndroid Build Coastguard Worker #else // DCHECK_IS_ON() 68*635a8641SAndroid Build Coastguard Worker #define THREAD_CHECKER(name) 69*635a8641SAndroid Build Coastguard Worker #define DCHECK_CALLED_ON_VALID_THREAD(name) EAT_STREAM_PARAMETERS 70*635a8641SAndroid Build Coastguard Worker #define DETACH_FROM_THREAD(name) 71*635a8641SAndroid Build Coastguard Worker #endif // DCHECK_IS_ON() 72*635a8641SAndroid Build Coastguard Worker 73*635a8641SAndroid Build Coastguard Worker namespace base { 74*635a8641SAndroid Build Coastguard Worker 75*635a8641SAndroid Build Coastguard Worker // Do nothing implementation, for use in release mode. 76*635a8641SAndroid Build Coastguard Worker // 77*635a8641SAndroid Build Coastguard Worker // Note: You should almost always use the ThreadChecker class (through the above 78*635a8641SAndroid Build Coastguard Worker // macros) to get the right version for your build configuration. 79*635a8641SAndroid Build Coastguard Worker class ThreadCheckerDoNothing { 80*635a8641SAndroid Build Coastguard Worker public: 81*635a8641SAndroid Build Coastguard Worker ThreadCheckerDoNothing() = default; CalledOnValidThread()82*635a8641SAndroid Build Coastguard Worker bool CalledOnValidThread() const WARN_UNUSED_RESULT { return true; } DetachFromThread()83*635a8641SAndroid Build Coastguard Worker void DetachFromThread() {} 84*635a8641SAndroid Build Coastguard Worker 85*635a8641SAndroid Build Coastguard Worker private: 86*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ThreadCheckerDoNothing); 87*635a8641SAndroid Build Coastguard Worker }; 88*635a8641SAndroid Build Coastguard Worker 89*635a8641SAndroid Build Coastguard Worker // Note that ThreadCheckerImpl::CalledOnValidThread() returns false when called 90*635a8641SAndroid Build Coastguard Worker // from tasks posted to SingleThreadTaskRunners bound to different sequences, 91*635a8641SAndroid Build Coastguard Worker // even if the tasks happen to run on the same thread (e.g. two independent 92*635a8641SAndroid Build Coastguard Worker // SingleThreadTaskRunners on the TaskScheduler that happen to share a thread). 93*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 94*635a8641SAndroid Build Coastguard Worker class ThreadChecker : public ThreadCheckerImpl { 95*635a8641SAndroid Build Coastguard Worker }; 96*635a8641SAndroid Build Coastguard Worker #else 97*635a8641SAndroid Build Coastguard Worker class ThreadChecker : public ThreadCheckerDoNothing { 98*635a8641SAndroid Build Coastguard Worker }; 99*635a8641SAndroid Build Coastguard Worker #endif // DCHECK_IS_ON() 100*635a8641SAndroid Build Coastguard Worker 101*635a8641SAndroid Build Coastguard Worker } // namespace base 102*635a8641SAndroid Build Coastguard Worker 103*635a8641SAndroid Build Coastguard Worker #endif // BASE_THREADING_THREAD_CHECKER_H_ 104