| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 | 
							- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
 
- // Use of this source code is governed by a BSD-style license that can be
 
- // found in the LICENSE file.
 
- #ifndef BASE_THREADING_THREAD_CHECKER_H_
 
- #define BASE_THREADING_THREAD_CHECKER_H_
 
- #include "base/check.h"
 
- #include "base/compiler_specific.h"
 
- #include "base/strings/string_piece.h"
 
- #include "base/thread_annotations.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).  It supports
 
- // thread safety annotations (see base/thread_annotations.h).
 
- //
 
- // 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(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(thread_checker_);
 
- //     }
 
- //
 
- //     void MyMethod() {
 
- //       DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
- //       ... (do stuff) ...
 
- //     }
 
- //
 
- //     void MyOtherMethod()
 
- //         VALID_CONTEXT_REQUIRED(thread_checker_) {
 
- //       foo_ = 42;
 
- //     }
 
- //
 
- //    private:
 
- //     int foo_ GUARDED_BY_CONTEXT(thread_checker_);
 
- //
 
- //     THREAD_CHECKER(thread_checker_);
 
- //   }
 
- #define THREAD_CHECKER_INTERNAL_CONCAT2(a, b) a##b
 
- #define THREAD_CHECKER_INTERNAL_CONCAT(a, b) \
 
-   THREAD_CHECKER_INTERNAL_CONCAT2(a, b)
 
- #define THREAD_CHECKER_INTERNAL_UID(prefix) \
 
-   THREAD_CHECKER_INTERNAL_CONCAT(prefix, __LINE__)
 
- #if DCHECK_IS_ON()
 
- #define THREAD_CHECKER(name) base::ThreadChecker name
 
- #define DCHECK_CALLED_ON_VALID_THREAD(name, ...)                 \
 
-   base::ScopedValidateThreadChecker THREAD_CHECKER_INTERNAL_UID( \
 
-       scoped_validate_thread_checker_)(name, ##__VA_ARGS__);
 
- #define DETACH_FROM_THREAD(name) (name).DetachFromThread()
 
- #else  // DCHECK_IS_ON()
 
- #define THREAD_CHECKER(name) static_assert(true, "")
 
- #define DCHECK_CALLED_ON_VALID_THREAD(name, ...) EAT_CHECK_STREAM_PARAMS()
 
- #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 (through the above
 
- // macros) to get the right version for your build configuration.
 
- // Note: This is only a check, not a "lock". It is marked "LOCKABLE" only in
 
- // order to support thread_annotations.h.
 
- class LOCKABLE ThreadCheckerDoNothing {
 
-  public:
 
-   ThreadCheckerDoNothing() = default;
 
-   // Moving between matching threads is allowed to help classes with
 
-   // ThreadCheckers that want a default move-construct/assign.
 
-   ThreadCheckerDoNothing(ThreadCheckerDoNothing&& other) = default;
 
-   ThreadCheckerDoNothing& operator=(ThreadCheckerDoNothing&& other) = default;
 
-   bool CalledOnValidThread() const WARN_UNUSED_RESULT { return true; }
 
-   void DetachFromThread() {}
 
-  private:
 
-   DISALLOW_COPY_AND_ASSIGN(ThreadCheckerDoNothing);
 
- };
 
- // 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 ThreadPool that happen to share a thread).
 
- #if DCHECK_IS_ON()
 
- class ThreadChecker : public ThreadCheckerImpl {
 
- };
 
- #else
 
- class ThreadChecker : public ThreadCheckerDoNothing {
 
- };
 
- #endif  // DCHECK_IS_ON()
 
- class SCOPED_LOCKABLE ScopedValidateThreadChecker {
 
-  public:
 
-   explicit ScopedValidateThreadChecker(const ThreadChecker& checker)
 
-       EXCLUSIVE_LOCK_FUNCTION(checker) {
 
-     DCHECK(checker.CalledOnValidThread());
 
-   }
 
-   explicit ScopedValidateThreadChecker(const ThreadChecker& checker,
 
-                                        const StringPiece& msg)
 
-       EXCLUSIVE_LOCK_FUNCTION(checker) {
 
-     DCHECK(checker.CalledOnValidThread()) << msg;
 
-   }
 
-   ~ScopedValidateThreadChecker() UNLOCK_FUNCTION() {}
 
-  private:
 
-   DISALLOW_COPY_AND_ASSIGN(ScopedValidateThreadChecker);
 
- };
 
- }  // namespace base
 
- #endif  // BASE_THREADING_THREAD_CHECKER_H_
 
 
  |