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_SEQUENCE_CHECKER_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_SEQUENCE_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/sequence_checker_impl.h" 11*635a8641SAndroid Build Coastguard Worker 12*635a8641SAndroid Build Coastguard Worker // SequenceChecker is a helper class used to help verify that some methods of a 13*635a8641SAndroid Build Coastguard Worker // class are called sequentially (for thread-safety). 14*635a8641SAndroid Build Coastguard Worker // 15*635a8641SAndroid Build Coastguard Worker // Use the macros below instead of the SequenceChecker directly so that the 16*635a8641SAndroid Build Coastguard Worker // unused member doesn't result in an extra byte (four when padded) per 17*635a8641SAndroid Build Coastguard Worker // instance in production. 18*635a8641SAndroid Build Coastguard Worker // 19*635a8641SAndroid Build Coastguard Worker // This class is much prefered to ThreadChecker for thread-safety checks. 20*635a8641SAndroid Build Coastguard Worker // ThreadChecker should only be used for classes that are truly thread-affine 21*635a8641SAndroid Build Coastguard Worker // (use thread-local-storage or a third-party API that does). 22*635a8641SAndroid Build Coastguard Worker // 23*635a8641SAndroid Build Coastguard Worker // Usage: 24*635a8641SAndroid Build Coastguard Worker // class MyClass { 25*635a8641SAndroid Build Coastguard Worker // public: 26*635a8641SAndroid Build Coastguard Worker // MyClass() { 27*635a8641SAndroid Build Coastguard Worker // // It's sometimes useful to detach on construction for objects that are 28*635a8641SAndroid Build Coastguard Worker // // constructed in one place and forever after used from another 29*635a8641SAndroid Build Coastguard Worker // // sequence. 30*635a8641SAndroid Build Coastguard Worker // DETACH_FROM_SEQUENCE(my_sequence_checker_); 31*635a8641SAndroid Build Coastguard Worker // } 32*635a8641SAndroid Build Coastguard Worker // 33*635a8641SAndroid Build Coastguard Worker // ~MyClass() { 34*635a8641SAndroid Build Coastguard Worker // // SequenceChecker doesn't automatically check it's destroyed on origin 35*635a8641SAndroid Build Coastguard Worker // // sequence for the same reason it's sometimes detached in the 36*635a8641SAndroid Build Coastguard Worker // // constructor. It's okay to destroy off sequence if the owner 37*635a8641SAndroid Build Coastguard Worker // // otherwise knows usage on the associated sequence is done. If you're 38*635a8641SAndroid Build Coastguard Worker // // not detaching in the constructor, you probably want to explicitly 39*635a8641SAndroid Build Coastguard Worker // // check in the destructor. 40*635a8641SAndroid Build Coastguard Worker // DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); 41*635a8641SAndroid Build Coastguard Worker // } 42*635a8641SAndroid Build Coastguard Worker // void MyMethod() { 43*635a8641SAndroid Build Coastguard Worker // DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); 44*635a8641SAndroid Build Coastguard Worker // ... (do stuff) ... 45*635a8641SAndroid Build Coastguard Worker // } 46*635a8641SAndroid Build Coastguard Worker // 47*635a8641SAndroid Build Coastguard Worker // private: 48*635a8641SAndroid Build Coastguard Worker // SEQUENCE_CHECKER(my_sequence_checker_); 49*635a8641SAndroid Build Coastguard Worker // } 50*635a8641SAndroid Build Coastguard Worker 51*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 52*635a8641SAndroid Build Coastguard Worker #define SEQUENCE_CHECKER(name) base::SequenceChecker name 53*635a8641SAndroid Build Coastguard Worker #define DCHECK_CALLED_ON_VALID_SEQUENCE(name) \ 54*635a8641SAndroid Build Coastguard Worker DCHECK((name).CalledOnValidSequence()) 55*635a8641SAndroid Build Coastguard Worker #define DETACH_FROM_SEQUENCE(name) (name).DetachFromSequence() 56*635a8641SAndroid Build Coastguard Worker #else // DCHECK_IS_ON() 57*635a8641SAndroid Build Coastguard Worker #define SEQUENCE_CHECKER(name) 58*635a8641SAndroid Build Coastguard Worker #define DCHECK_CALLED_ON_VALID_SEQUENCE(name) EAT_STREAM_PARAMETERS 59*635a8641SAndroid Build Coastguard Worker #define DETACH_FROM_SEQUENCE(name) 60*635a8641SAndroid Build Coastguard Worker #endif // DCHECK_IS_ON() 61*635a8641SAndroid Build Coastguard Worker 62*635a8641SAndroid Build Coastguard Worker namespace base { 63*635a8641SAndroid Build Coastguard Worker 64*635a8641SAndroid Build Coastguard Worker // Do nothing implementation, for use in release mode. 65*635a8641SAndroid Build Coastguard Worker // 66*635a8641SAndroid Build Coastguard Worker // Note: You should almost always use the SequenceChecker class (through the 67*635a8641SAndroid Build Coastguard Worker // above macros) to get the right version for your build configuration. 68*635a8641SAndroid Build Coastguard Worker class SequenceCheckerDoNothing { 69*635a8641SAndroid Build Coastguard Worker public: 70*635a8641SAndroid Build Coastguard Worker SequenceCheckerDoNothing() = default; CalledOnValidSequence()71*635a8641SAndroid Build Coastguard Worker bool CalledOnValidSequence() const WARN_UNUSED_RESULT { return true; } DetachFromSequence()72*635a8641SAndroid Build Coastguard Worker void DetachFromSequence() {} 73*635a8641SAndroid Build Coastguard Worker 74*635a8641SAndroid Build Coastguard Worker private: 75*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(SequenceCheckerDoNothing); 76*635a8641SAndroid Build Coastguard Worker }; 77*635a8641SAndroid Build Coastguard Worker 78*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 79*635a8641SAndroid Build Coastguard Worker class SequenceChecker : public SequenceCheckerImpl { 80*635a8641SAndroid Build Coastguard Worker }; 81*635a8641SAndroid Build Coastguard Worker #else 82*635a8641SAndroid Build Coastguard Worker class SequenceChecker : public SequenceCheckerDoNothing { 83*635a8641SAndroid Build Coastguard Worker }; 84*635a8641SAndroid Build Coastguard Worker #endif // DCHECK_IS_ON() 85*635a8641SAndroid Build Coastguard Worker 86*635a8641SAndroid Build Coastguard Worker } // namespace base 87*635a8641SAndroid Build Coastguard Worker 88*635a8641SAndroid Build Coastguard Worker #endif // BASE_SEQUENCE_CHECKER_H_ 89