1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 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_IMPL_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_THREADING_THREAD_CHECKER_IMPL_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <memory> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 11*6777b538SAndroid Build Coastguard Worker #include "base/sequence_token.h" 12*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/thread_annotations.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread_ref.h" 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker namespace base { 17*6777b538SAndroid Build Coastguard Worker namespace debug { 18*6777b538SAndroid Build Coastguard Worker class StackTrace; 19*6777b538SAndroid Build Coastguard Worker } 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker class SequenceCheckerImpl; 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker // Real implementation of ThreadChecker, for use in debug mode, or for temporary 24*6777b538SAndroid Build Coastguard Worker // use in release mode (e.g. to CHECK on a threading issue seen only in the 25*6777b538SAndroid Build Coastguard Worker // wild). 26*6777b538SAndroid Build Coastguard Worker // 27*6777b538SAndroid Build Coastguard Worker // Note: You should almost always use the ThreadChecker class to get the right 28*6777b538SAndroid Build Coastguard Worker // version for your build configuration. 29*6777b538SAndroid Build Coastguard Worker // Note: This is only a check, not a "lock". It is marked "LOCKABLE" only in 30*6777b538SAndroid Build Coastguard Worker // order to support thread_annotations.h. 31*6777b538SAndroid Build Coastguard Worker class LOCKABLE BASE_EXPORT ThreadCheckerImpl { 32*6777b538SAndroid Build Coastguard Worker public: 33*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl(); 34*6777b538SAndroid Build Coastguard Worker ~ThreadCheckerImpl(); 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Worker // Allow move construct/assign. This must be called on |other|'s associated 37*6777b538SAndroid Build Coastguard Worker // thread and assignment can only be made into a ThreadCheckerImpl which is 38*6777b538SAndroid Build Coastguard Worker // detached or already associated with the current thread. This isn't 39*6777b538SAndroid Build Coastguard Worker // thread-safe (|this| and |other| shouldn't be in use while this move is 40*6777b538SAndroid Build Coastguard Worker // performed). If the assignment was legal, the resulting ThreadCheckerImpl 41*6777b538SAndroid Build Coastguard Worker // will be bound to the current thread and |other| will be detached. 42*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl(ThreadCheckerImpl&& other); 43*6777b538SAndroid Build Coastguard Worker ThreadCheckerImpl& operator=(ThreadCheckerImpl&& other); 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker // On returning false, if logging is enabled with EnableStackLogging() and 46*6777b538SAndroid Build Coastguard Worker // `out_bound_at` is not null, this method allocates a StackTrace and returns 47*6777b538SAndroid Build Coastguard Worker // it in the out-parameter, storing inside it the stack from where the failing 48*6777b538SAndroid Build Coastguard Worker // ThreadChecker was bound to its thread. 49*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool CalledOnValidThread( 50*6777b538SAndroid Build Coastguard Worker std::unique_ptr<debug::StackTrace>* out_bound_at = nullptr) const 51*6777b538SAndroid Build Coastguard Worker LOCKS_EXCLUDED(lock_); 52*6777b538SAndroid Build Coastguard Worker 53*6777b538SAndroid Build Coastguard Worker // Changes the thread that is checked for in CalledOnValidThread. This may 54*6777b538SAndroid Build Coastguard Worker // be useful when an object may be created on one thread and then used 55*6777b538SAndroid Build Coastguard Worker // exclusively on another thread. 56*6777b538SAndroid Build Coastguard Worker void DetachFromThread() LOCKS_EXCLUDED(lock_); 57*6777b538SAndroid Build Coastguard Worker 58*6777b538SAndroid Build Coastguard Worker private: 59*6777b538SAndroid Build Coastguard Worker friend class SequenceCheckerImpl; 60*6777b538SAndroid Build Coastguard Worker 61*6777b538SAndroid Build Coastguard Worker // Private because it's only called by 62*6777b538SAndroid Build Coastguard Worker // `SequenceCheckerImpl::EnableStackLogging()`. 63*6777b538SAndroid Build Coastguard Worker static void EnableStackLogging(); 64*6777b538SAndroid Build Coastguard Worker 65*6777b538SAndroid Build Coastguard Worker // Returns ownership of a pointer to StackTrace where the ThreadCheckerImpl 66*6777b538SAndroid Build Coastguard Worker // was bound for debug logs, or nullptr if such logging was not enabled at 67*6777b538SAndroid Build Coastguard Worker // the time. 68*6777b538SAndroid Build Coastguard Worker std::unique_ptr<debug::StackTrace> GetBoundAt() const 69*6777b538SAndroid Build Coastguard Worker EXCLUSIVE_LOCKS_REQUIRED(lock_); 70*6777b538SAndroid Build Coastguard Worker 71*6777b538SAndroid Build Coastguard Worker void EnsureAssigned() const EXCLUSIVE_LOCKS_REQUIRED(lock_); 72*6777b538SAndroid Build Coastguard Worker 73*6777b538SAndroid Build Coastguard Worker // Members are mutable so that CalledOnValidThread() can set them. 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker // Synchronizes access to all members. 76*6777b538SAndroid Build Coastguard Worker mutable base::Lock lock_; 77*6777b538SAndroid Build Coastguard Worker 78*6777b538SAndroid Build Coastguard Worker // Stack from which this was bound (set if `EnableStackLogging()` was called). 79*6777b538SAndroid Build Coastguard Worker mutable std::unique_ptr<debug::StackTrace> bound_at_ GUARDED_BY(lock_); 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker // Thread on which CalledOnValidThread() may return true. 82*6777b538SAndroid Build Coastguard Worker mutable PlatformThreadRef thread_ref_ GUARDED_BY(lock_); 83*6777b538SAndroid Build Coastguard Worker 84*6777b538SAndroid Build Coastguard Worker // TaskToken for which CalledOnValidThread() always returns true. This allows 85*6777b538SAndroid Build Coastguard Worker // CalledOnValidThread() to return true when called multiple times from the 86*6777b538SAndroid Build Coastguard Worker // same task, even if it's not running in a single-threaded context itself 87*6777b538SAndroid Build Coastguard Worker // (allowing usage of ThreadChecker objects on the stack in the scope of one- 88*6777b538SAndroid Build Coastguard Worker // off tasks). Note: CalledOnValidThread() may return true even if the current 89*6777b538SAndroid Build Coastguard Worker // TaskToken is not equal to this. 90*6777b538SAndroid Build Coastguard Worker mutable internal::TaskToken task_token_ GUARDED_BY(lock_); 91*6777b538SAndroid Build Coastguard Worker 92*6777b538SAndroid Build Coastguard Worker // SequenceToken for which CalledOnValidThread() may return true. Used to 93*6777b538SAndroid Build Coastguard Worker // ensure that CalledOnValidThread() doesn't return true for ThreadPool 94*6777b538SAndroid Build Coastguard Worker // tasks that happen to run on the same thread but weren't posted to the same 95*6777b538SAndroid Build Coastguard Worker // SingleThreadTaskRunner. 96*6777b538SAndroid Build Coastguard Worker mutable internal::SequenceToken sequence_token_ GUARDED_BY(lock_); 97*6777b538SAndroid Build Coastguard Worker }; 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker } // namespace base 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker #endif // BASE_THREADING_THREAD_CHECKER_IMPL_H_ 102