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