Chromium Code Reviews| Index: base/threading/thread_checker.h |
| diff --git a/base/threading/thread_checker.h b/base/threading/thread_checker.h |
| index 1d4eb1c7b0b00ad79dbec27d1afb0238190d8fa2..91e3aa9acd66cacc2cc552b6fa6f294dc585bfd9 100644 |
| --- a/base/threading/thread_checker.h |
| +++ b/base/threading/thread_checker.h |
| @@ -8,12 +8,63 @@ |
| #include "base/logging.h" |
| #include "base/threading/thread_checker_impl.h" |
| +// ThreadChecker is a helper class used to help verify that some methods of a |
| +// class are called from the same thread (for thread-affinity). |
| +// |
| +// Use the macros below instead of the ThreadChecker directly so that the unused |
| +// member doesn't result in an extra byte (four when padded) per instance in |
| +// production. |
| +// |
| +// Usage of this class should be *rare* as most classes require thread-safety |
| +// but not thread-affinity. Prefer base::SequenceChecker to verify thread-safe |
| +// access. |
| +// |
| +// Thread-affinity checks should only be required in classes that use thread- |
| +// local-storage or a third-party API that does. |
| +// |
| +// Prefer to encode the minimum requirements of each class instead of the |
| +// environment it happens to run in today. e.g. if a class requires thread- |
| +// safety but not thread-affinity, use a SequenceChecker even if it happens to |
| +// run on a SingleThreadTaskRunner today. That makes it easier to understand |
| +// what would need to change to turn that SingleThreadTaskRunner into a |
| +// SequencedTaskRunner for ease of scheduling as well as minimizes side-effects |
| +// if that change is made. |
| +// |
| +// Usage: |
| +// class MyClass { |
| +// public: |
| +// MyClass() { |
| +// // It's sometimes useful to detach on construction for objects that are |
| +// // constructed in one place and forever after used from another |
| +// // thread. |
| +// DETACH_FROM_THREAD(my_thread_checker_); |
| +// } |
| +// |
| +// void MyMethod() { |
|
danakj
2017/05/09 16:04:28
same
gab
2017/05/10 15:40:08
Done.
|
| +// DCHECK_CALLED_ON_VALID_THREAD(my_thread_checker_); |
| +// ... (do stuff) ... |
| +// } |
| +// |
| +// private: |
| +// THREAD_CHECKER(my_thread_checker_); |
| +// } |
| + |
| +#if DCHECK_IS_ON() |
| +#define THREAD_CHECKER(name) base::ThreadChecker name |
| +#define DCHECK_CALLED_ON_VALID_THREAD(name) DCHECK((name).CalledOnValidThread()) |
| +#define DETACH_FROM_THREAD(name) (name).DetachFromThread() |
| +#else // DCHECK_IS_ON() |
| +#define THREAD_CHECKER(name) |
| +#define DCHECK_CALLED_ON_VALID_THREAD(name) |
| +#define DETACH_FROM_THREAD(name) |
| +#endif // DCHECK_IS_ON() |
| + |
| namespace base { |
| // Do nothing implementation, for use in release mode. |
| // |
| -// Note: You should almost always use the ThreadChecker class to get the |
| -// right version for your build configuration. |
| +// Note: You should almost always use the ThreadChecker class (through the above |
| +// macros) to get the right version for your build configuration. |
| class ThreadCheckerDoNothing { |
| public: |
| bool CalledOnValidThread() const WARN_UNUSED_RESULT { |
| @@ -23,43 +74,10 @@ class ThreadCheckerDoNothing { |
| void DetachFromThread() {} |
| }; |
| -// ThreadChecker is a helper class used to help verify that some methods of a |
| -// class are called from the same thread. It provides identical functionality to |
| -// base::NonThreadSafe, but it is meant to be held as a member variable, rather |
| -// than inherited from base::NonThreadSafe. |
| -// |
| -// While inheriting from base::NonThreadSafe may give a clear indication about |
| -// the thread-safety of a class, it may also lead to violations of the style |
| -// guide with regard to multiple inheritance. The choice between having a |
| -// ThreadChecker member and inheriting from base::NonThreadSafe should be based |
| -// on whether: |
| -// - Derived classes need to know the thread they belong to, as opposed to |
| -// having that functionality fully encapsulated in the base class. |
| -// - Derived classes should be able to reassign the base class to another |
| -// thread, via DetachFromThread. |
| -// |
| -// If neither of these are true, then having a ThreadChecker member and calling |
| -// CalledOnValidThread is the preferable solution. |
| -// |
| -// Example: |
| -// class MyClass { |
| -// public: |
| -// void Foo() { |
| -// DCHECK(thread_checker_.CalledOnValidThread()); |
| -// ... (do stuff) ... |
| -// } |
| -// |
| -// private: |
| -// ThreadChecker thread_checker_; |
| -// } |
| -// |
| -// Note that, when enabled, CalledOnValidThread() returns false when called from |
| -// tasks posted to SingleThreadTaskRunners bound to different sequences, even if |
| -// the tasks happen to run on the same thread (e.g. two independent TaskRunners |
| -// with ExecutionMode::SINGLE_THREADED on the TaskScheduler that happen to share |
| -// a thread). |
| -// |
| -// In Release mode, CalledOnValidThread will always return true. |
| +// Note that ThreadCheckerImpl::CalledOnValidThread() returns false when called |
| +// from tasks posted to SingleThreadTaskRunners bound to different sequences, |
| +// even if the tasks happen to run on the same thread (e.g. two independent |
| +// SingleThreadTaskRunners on the TaskScheduler that happen to share a thread). |
| #if DCHECK_IS_ON() |
| class ThreadChecker : public ThreadCheckerImpl { |
| }; |