thread_checker.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. #ifndef BASE_THREADING_THREAD_CHECKER_H_
  5. #define BASE_THREADING_THREAD_CHECKER_H_
  6. #include "base/check.h"
  7. #include "base/compiler_specific.h"
  8. #include "base/strings/string_piece.h"
  9. #include "base/thread_annotations.h"
  10. #include "base/threading/thread_checker_impl.h"
  11. // ThreadChecker is a helper class used to help verify that some methods of a
  12. // class are called from the same thread (for thread-affinity). It supports
  13. // thread safety annotations (see base/thread_annotations.h).
  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(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(thread_checker_);
  52. // }
  53. //
  54. // void MyMethod() {
  55. // DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  56. // ... (do stuff) ...
  57. // }
  58. //
  59. // void MyOtherMethod()
  60. // VALID_CONTEXT_REQUIRED(thread_checker_) {
  61. // foo_ = 42;
  62. // }
  63. //
  64. // private:
  65. // int foo_ GUARDED_BY_CONTEXT(thread_checker_);
  66. //
  67. // THREAD_CHECKER(thread_checker_);
  68. // }
  69. #define THREAD_CHECKER_INTERNAL_CONCAT2(a, b) a##b
  70. #define THREAD_CHECKER_INTERNAL_CONCAT(a, b) \
  71. THREAD_CHECKER_INTERNAL_CONCAT2(a, b)
  72. #define THREAD_CHECKER_INTERNAL_UID(prefix) \
  73. THREAD_CHECKER_INTERNAL_CONCAT(prefix, __LINE__)
  74. #if DCHECK_IS_ON()
  75. #define THREAD_CHECKER(name) base::ThreadChecker name
  76. #define DCHECK_CALLED_ON_VALID_THREAD(name, ...) \
  77. base::ScopedValidateThreadChecker THREAD_CHECKER_INTERNAL_UID( \
  78. scoped_validate_thread_checker_)(name, ##__VA_ARGS__);
  79. #define DETACH_FROM_THREAD(name) (name).DetachFromThread()
  80. #else // DCHECK_IS_ON()
  81. #define THREAD_CHECKER(name) static_assert(true, "")
  82. #define DCHECK_CALLED_ON_VALID_THREAD(name, ...) EAT_CHECK_STREAM_PARAMS()
  83. #define DETACH_FROM_THREAD(name)
  84. #endif // DCHECK_IS_ON()
  85. namespace base {
  86. // Do nothing implementation, for use in release mode.
  87. //
  88. // Note: You should almost always use the ThreadChecker class (through the above
  89. // macros) to get the right version for your build configuration.
  90. // Note: This is only a check, not a "lock". It is marked "LOCKABLE" only in
  91. // order to support thread_annotations.h.
  92. class LOCKABLE ThreadCheckerDoNothing {
  93. public:
  94. ThreadCheckerDoNothing() = default;
  95. // Moving between matching threads is allowed to help classes with
  96. // ThreadCheckers that want a default move-construct/assign.
  97. ThreadCheckerDoNothing(ThreadCheckerDoNothing&& other) = default;
  98. ThreadCheckerDoNothing& operator=(ThreadCheckerDoNothing&& other) = default;
  99. bool CalledOnValidThread() const WARN_UNUSED_RESULT { return true; }
  100. void DetachFromThread() {}
  101. private:
  102. DISALLOW_COPY_AND_ASSIGN(ThreadCheckerDoNothing);
  103. };
  104. // Note that ThreadCheckerImpl::CalledOnValidThread() returns false when called
  105. // from tasks posted to SingleThreadTaskRunners bound to different sequences,
  106. // even if the tasks happen to run on the same thread (e.g. two independent
  107. // SingleThreadTaskRunners on the ThreadPool that happen to share a thread).
  108. #if DCHECK_IS_ON()
  109. class ThreadChecker : public ThreadCheckerImpl {
  110. };
  111. #else
  112. class ThreadChecker : public ThreadCheckerDoNothing {
  113. };
  114. #endif // DCHECK_IS_ON()
  115. class SCOPED_LOCKABLE ScopedValidateThreadChecker {
  116. public:
  117. explicit ScopedValidateThreadChecker(const ThreadChecker& checker)
  118. EXCLUSIVE_LOCK_FUNCTION(checker) {
  119. DCHECK(checker.CalledOnValidThread());
  120. }
  121. explicit ScopedValidateThreadChecker(const ThreadChecker& checker,
  122. const StringPiece& msg)
  123. EXCLUSIVE_LOCK_FUNCTION(checker) {
  124. DCHECK(checker.CalledOnValidThread()) << msg;
  125. }
  126. ~ScopedValidateThreadChecker() UNLOCK_FUNCTION() {}
  127. private:
  128. DISALLOW_COPY_AND_ASSIGN(ScopedValidateThreadChecker);
  129. };
  130. } // namespace base
  131. #endif // BASE_THREADING_THREAD_CHECKER_H_