1 // Copyright 2012 The Chromium Authors 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_SEQUENCE_CHECKER_IMPL_H_ 6 #define BASE_SEQUENCE_CHECKER_IMPL_H_ 7 8 #include <memory> 9 10 #include "base/base_export.h" 11 #include "base/synchronization/lock.h" 12 #include "base/thread_annotations.h" 13 #include "base/threading/thread_checker_impl.h" 14 15 namespace base { 16 namespace debug { 17 class StackTrace; 18 } 19 20 // Real implementation of SequenceChecker for use in debug mode or for temporary 21 // use in release mode (e.g. to CHECK on a threading issue seen only in the 22 // wild). 23 // 24 // Note: You should almost always use the SequenceChecker class to get the right 25 // version for your build configuration. 26 // Note: This is marked with "context" capability in order to support 27 // thread_annotations.h. 28 class THREAD_ANNOTATION_ATTRIBUTE__(capability("context")) 29 BASE_EXPORT SequenceCheckerImpl { 30 public: 31 static void EnableStackLogging(); 32 33 SequenceCheckerImpl(); 34 35 // Allow move construct/assign. This must be called on |other|'s associated 36 // sequence and assignment can only be made into a SequenceCheckerImpl which 37 // is detached or already associated with the current sequence. This isn't 38 // thread-safe (|this| and |other| shouldn't be in use while this move is 39 // performed). If the assignment was legal, the resulting SequenceCheckerImpl 40 // will be bound to the current sequence and |other| will be detached. 41 SequenceCheckerImpl(SequenceCheckerImpl&& other); 42 SequenceCheckerImpl& operator=(SequenceCheckerImpl&& other); 43 SequenceCheckerImpl(const SequenceCheckerImpl&) = delete; 44 SequenceCheckerImpl& operator=(const SequenceCheckerImpl&) = delete; 45 ~SequenceCheckerImpl(); 46 47 // Returns true if called in sequence with previous calls to this method and 48 // the constructor. 49 // On returning false, if logging is enabled with EnableStackLogging() and 50 // `out_bound_at` is not null, this method allocates a StackTrace and returns 51 // it in the out-parameter, storing inside it the stack from where the failing 52 // SequenceChecker was bound to its sequence. Otherwise, out_bound_at is left 53 // untouched. 54 [[nodiscard]] bool CalledOnValidSequence( 55 std::unique_ptr<debug::StackTrace>* out_bound_at = nullptr) const; 56 57 // Unbinds the checker from the currently associated sequence. The checker 58 // will be re-bound on the next call to CalledOnValidSequence(). 59 void DetachFromSequence(); 60 61 private: 62 // SequenceCheckerImpl uses ThreadCheckerImpl for shared storage. 63 ThreadCheckerImpl thread_checker_; 64 }; 65 66 } // namespace base 67 68 #endif // BASE_SEQUENCE_CHECKER_IMPL_H_ 69