| Index: base/threading/thread_checker.h
|
| diff --git a/base/threading/thread_checker.h b/base/threading/thread_checker.h
|
| index 1d4eb1c7b0b00ad79dbec27d1afb0238190d8fa2..9a6b4b8e9eac879abb3b6d34403766c00392f48f 100644
|
| --- a/base/threading/thread_checker.h
|
| +++ b/base/threading/thread_checker.h
|
| @@ -8,12 +8,73 @@
|
| #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_);
|
| +// }
|
| +//
|
| +// ~MyClass() {
|
| +// // ThreadChecker doesn't automatically check it's destroyed on origin
|
| +// // thread for the same reason it's sometimes detached in the
|
| +// // constructor. It's okay to destroy off thread if the owner otherwise
|
| +// // knows usage on the associated thread is done. If you're not
|
| +// // detaching in the constructor, you probably want to explicitly check
|
| +// // in the destructor.
|
| +// DCHECK_CALLED_ON_VALID_THREAD(my_thread_checker_);
|
| +// }
|
| +//
|
| +// void MyMethod() {
|
| +// 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 +84,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 {
|
| };
|
|
|