OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_SEQUENCE_CHECKER_H_ | 5 #ifndef BASE_SEQUENCE_CHECKER_H_ |
6 #define BASE_SEQUENCE_CHECKER_H_ | 6 #define BASE_SEQUENCE_CHECKER_H_ |
7 | 7 |
| 8 #include "base/logging.h" |
8 #include "base/sequence_checker_impl.h" | 9 #include "base/sequence_checker_impl.h" |
9 | 10 |
| 11 // SequenceChecker is a helper class used to help verify that some methods of a |
| 12 // class are called sequentially (for thread-safety). |
| 13 // |
| 14 // Use the macros below instead of the SequenceChecker directly so that the |
| 15 // unused member doesn't result in an extra byte (four when padded) per |
| 16 // instance in production. |
| 17 // |
| 18 // This class is much prefered to ThreadChecker for thread-safety checks. |
| 19 // ThreadChecker should only be used for classes that are truly thread-affine |
| 20 // (use thread-local-storage or a third-party API that does). |
| 21 // |
| 22 // Usage: |
| 23 // class MyClass { |
| 24 // public: |
| 25 // MyClass() { |
| 26 // // It's sometimes useful to detach on construction for objects that are |
| 27 // // constructed in one place and forever after used from another |
| 28 // // sequence. |
| 29 // DETACH_FROM_SEQUENCE(my_sequence_checker_); |
| 30 // } |
| 31 // |
| 32 // ~MyClass() { |
| 33 // // SequenceChecker doesn't automatically check it's destroyed on origin |
| 34 // // sequence for the same reason it's sometimes detached in the |
| 35 // // constructor. It's okay to destroy off sequence if the owner |
| 36 // // otherwise knows usage on the associated sequence is done. If you're |
| 37 // // not detaching in the constructor, you probably want to explicitly |
| 38 // // check in the destructor. |
| 39 // DCHECK_CALLED_ON_VALID_THREAD(my_thread_checker_); |
| 40 // } |
| 41 // void MyMethod() { |
| 42 // DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); |
| 43 // ... (do stuff) ... |
| 44 // } |
| 45 // |
| 46 // private: |
| 47 // SEQUENCE_CHECKER(my_sequence_checker_); |
| 48 // } |
| 49 |
| 50 #if DCHECK_IS_ON() |
| 51 #define SEQUENCE_CHECKER(name) base::SequenceChecker name |
| 52 #define DCHECK_CALLED_ON_VALID_SEQUENCE(name) \ |
| 53 DCHECK((name).CalledOnValidSequence()) |
| 54 #define DETACH_FROM_SEQUENCE(name) (name).DetachFromSequence() |
| 55 #else // DCHECK_IS_ON() |
| 56 #define SEQUENCE_CHECKER(name) |
| 57 #define DCHECK_CALLED_ON_VALID_SEQUENCE(name) |
| 58 #define DETACH_FROM_SEQUENCE(name) |
| 59 #endif // DCHECK_IS_ON() |
| 60 |
10 namespace base { | 61 namespace base { |
11 | 62 |
12 // Do nothing implementation, for use in release mode. | 63 // Do nothing implementation, for use in release mode. |
13 // | 64 // |
14 // Note: You should almost always use the SequenceChecker class to get | 65 // Note: You should almost always use the SequenceChecker class (through the |
15 // the right version for your build configuration. | 66 // above macros) to get the right version for your build configuration. |
16 class SequenceCheckerDoNothing { | 67 class SequenceCheckerDoNothing { |
17 public: | 68 public: |
18 bool CalledOnValidSequence() const { return true; } | 69 bool CalledOnValidSequence() const { return true; } |
19 | 70 |
20 void DetachFromSequence() {} | 71 void DetachFromSequence() {} |
21 }; | 72 }; |
22 | 73 |
23 // SequenceChecker is a helper class to verify that calls to some methods of a | |
24 // class are sequenced. Calls are sequenced when they are issued: | |
25 // - From tasks posted to SequencedTaskRunners or SingleThreadTaskRunners bound | |
26 // to the same sequence, or, | |
27 // - From a single thread outside of any task. | |
28 // | |
29 // Example: | |
30 // class MyClass { | |
31 // public: | |
32 // void Foo() { | |
33 // DCHECK(sequence_checker_.CalledOnValidSequence()); | |
34 // ... (do stuff) ... | |
35 // } | |
36 // | |
37 // private: | |
38 // SequenceChecker sequence_checker_; | |
39 // } | |
40 // | |
41 // In Release mode, CalledOnValidSequence() will always return true. | |
42 #if DCHECK_IS_ON() | 74 #if DCHECK_IS_ON() |
43 class SequenceChecker : public SequenceCheckerImpl { | 75 class SequenceChecker : public SequenceCheckerImpl { |
44 }; | 76 }; |
45 #else | 77 #else |
46 class SequenceChecker : public SequenceCheckerDoNothing { | 78 class SequenceChecker : public SequenceCheckerDoNothing { |
47 }; | 79 }; |
48 #endif // DCHECK_IS_ON() | 80 #endif // DCHECK_IS_ON() |
49 | 81 |
50 } // namespace base | 82 } // namespace base |
51 | 83 |
52 #endif // BASE_SEQUENCE_CHECKER_H_ | 84 #endif // BASE_SEQUENCE_CHECKER_H_ |
OLD | NEW |