tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

thread_checker_impl.h (4360B)


      1 // Copyright 2011 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_THREADING_THREAD_CHECKER_IMPL_H_
      6 #define BASE_THREADING_THREAD_CHECKER_IMPL_H_
      7 
      8 #include <memory>
      9 
     10 #include "base/base_export.h"
     11 #include "base/sequence_token.h"
     12 #include "base/synchronization/lock.h"
     13 #include "base/thread_annotations.h"
     14 #include "base/threading/platform_thread_ref.h"
     15 
     16 namespace base {
     17 namespace debug {
     18 class StackTrace;
     19 }
     20 
     21 class SequenceCheckerImpl;
     22 
     23 // Real implementation of ThreadChecker, for use in debug mode, or for temporary
     24 // use in release mode (e.g. to CHECK on a threading issue seen only in the
     25 // wild).
     26 //
     27 // Note: You should almost always use the ThreadChecker class to get the right
     28 // version for your build configuration.
     29 // Note: This is only a check, not a "lock". It is marked "LOCKABLE" only in
     30 // order to support thread_annotations.h.
     31 class LOCKABLE BASE_EXPORT ThreadCheckerImpl {
     32 public:
     33  static void EnableStackLogging();
     34 
     35  ThreadCheckerImpl();
     36  ~ThreadCheckerImpl();
     37 
     38  // Allow move construct/assign. This must be called on |other|'s associated
     39  // thread and assignment can only be made into a ThreadCheckerImpl which is
     40  // detached or already associated with the current thread. This isn't
     41  // thread-safe (|this| and |other| shouldn't be in use while this move is
     42  // performed). If the assignment was legal, the resulting ThreadCheckerImpl
     43  // will be bound to the current thread and |other| will be detached.
     44  ThreadCheckerImpl(ThreadCheckerImpl&& other);
     45  ThreadCheckerImpl& operator=(ThreadCheckerImpl&& other);
     46 
     47  // On returning false, if logging is enabled with EnableStackLogging() and
     48  // `out_bound_at` is not null, this method allocates a StackTrace and returns
     49  // it in the out-parameter, storing inside it the stack from where the failing
     50  // ThreadChecker was bound to its thread.
     51  [[nodiscard]] bool CalledOnValidThread(
     52      std::unique_ptr<debug::StackTrace>* out_bound_at = nullptr) const
     53      LOCKS_EXCLUDED(lock_);
     54 
     55  // Changes the thread that is checked for in CalledOnValidThread.  This may
     56  // be useful when an object may be created on one thread and then used
     57  // exclusively on another thread.
     58  void DetachFromThread() LOCKS_EXCLUDED(lock_);
     59 
     60 private:
     61  // This shares storage with SequenceCheckerImpl.
     62  friend class SequenceCheckerImpl;
     63 
     64  [[nodiscard]] bool CalledOnValidThreadInternal(
     65      std::unique_ptr<debug::StackTrace>* out_bound_at) const
     66      EXCLUSIVE_LOCKS_REQUIRED(lock_);
     67 
     68  // Returns ownership of a pointer to StackTrace where the ThreadCheckerImpl
     69  // was bound for debug logs, or nullptr if such logging was not enabled at
     70  // the time.
     71  std::unique_ptr<debug::StackTrace> GetBoundAt() const
     72      EXCLUSIVE_LOCKS_REQUIRED(lock_);
     73 
     74  void EnsureAssigned() const EXCLUSIVE_LOCKS_REQUIRED(lock_);
     75 
     76  // Members are mutable so that CalledOnValidThread() can set them.
     77 
     78  // Synchronizes access to all members.
     79  mutable base::Lock lock_;
     80 
     81  // The location where the ThreadChecker was bound to the current
     82  // thread/task/sequence. Default-initialized with 0 frames until bound.
     83  mutable std::unique_ptr<debug::StackTrace> bound_at_ GUARDED_BY(lock_);
     84 
     85  // Thread on which CalledOnValidThread() may return true.
     86  mutable PlatformThreadRef thread_id_ GUARDED_BY(lock_);
     87 
     88  // TaskToken for which CalledOnValidThread() always returns true. This allows
     89  // CalledOnValidThread() to return true when called multiple times from the
     90  // same task, even if it's not running in a single-threaded context itself
     91  // (allowing usage of ThreadChecker objects on the stack in the scope of one-
     92  // off tasks). Note: CalledOnValidThread() may return true even if the current
     93  // TaskToken is not equal to this.
     94  mutable TaskToken task_token_ GUARDED_BY(lock_);
     95 
     96  // SequenceToken for which CalledOnValidThread() may return true. Used to
     97  // ensure that CalledOnValidThread() doesn't return true for ThreadPool
     98  // tasks that happen to run on the same thread but weren't posted to the same
     99  // SingleThreadTaskRunner.
    100  //
    101  // Also used for SequenceCheckerImpl's CalledOnValidSequence(), as this shares
    102  // storage. See SequenceCheckerImpl.
    103  mutable SequenceToken sequence_token_ GUARDED_BY(lock_);
    104 };
    105 
    106 }  // namespace base
    107 
    108 #endif  // BASE_THREADING_THREAD_CHECKER_IMPL_H_