tor-browser

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

single_thread_task_runner.h (7154B)


      1 // Copyright 2012 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_TASK_SINGLE_THREAD_TASK_RUNNER_H_
      6 #define BASE_TASK_SINGLE_THREAD_TASK_RUNNER_H_
      7 
      8 #include "base/auto_reset.h"
      9 #include "base/base_export.h"
     10 #include "base/dcheck_is_on.h"
     11 #include "base/gtest_prod_util.h"
     12 #include "base/memory/raw_ptr_exclusion.h"
     13 #include "base/task/sequenced_task_runner.h"
     14 #include "third_party/abseil-cpp/absl/types/optional.h"
     15 
     16 namespace blink::scheduler {
     17 class MainThreadSchedulerImpl;
     18 }  // namespace blink::scheduler
     19 
     20 namespace base {
     21 
     22 class ScopedDisallowRunningRunLoop;
     23 
     24 // A SingleThreadTaskRunner is a SequencedTaskRunner with one more
     25 // guarantee; namely, that all tasks are run on a single dedicated
     26 // thread.  Most use cases require only a SequencedTaskRunner, unless
     27 // there is a specific need to run tasks on only a single thread.
     28 //
     29 // SingleThreadTaskRunner implementations might:
     30 //   - Post tasks to an existing thread's MessageLoop (see
     31 //     MessageLoop::task_runner()).
     32 //   - Create their own worker thread and MessageLoop to post tasks to.
     33 //   - Add tasks to a FIFO and signal to a non-MessageLoop thread for them to
     34 //     be processed. This allows TaskRunner-oriented code run on threads
     35 //     running other kinds of message loop, e.g. Jingle threads.
     36 class BASE_EXPORT SingleThreadTaskRunner : public SequencedTaskRunner {
     37 public:
     38  // A more explicit alias to RunsTasksInCurrentSequence().
     39  bool BelongsToCurrentThread() const { return RunsTasksInCurrentSequence(); }
     40 
     41  // Returns the default SingleThreadTaskRunner for the current thread.
     42  // On threads that service multiple task queues, the default task queue is
     43  // preferred to inheriting the current task queue (otherwise, everything would
     44  // implicitly be "input priority"...). If the caller knows which task queue it
     45  // should be running on, it should post to that SingleThreadTaskRunner
     46  // directly instead of GetCurrentDefault(). This is critical in some
     47  // cases, e.g. DeleteSoon or RefCountedDeleteOnSequence should delete the
     48  // object on the same task queue it's used from (or on a lower priority).
     49  //
     50  // DCHECKs if the current thread isn't servicing a SingleThreadTaskRunner.
     51  //
     52  // See
     53  // https://chromium.googlesource.com/chromium/src/+/main/docs/threading_and_tasks.md#Posting-to-the-Current-Virtual_Thread
     54  // for details
     55 
     56  [[nodiscard]] static const scoped_refptr<SingleThreadTaskRunner>&
     57  GetCurrentDefault();
     58 
     59  // Returns true if the SingleThreadTaskRunner is already created for
     60  // the current thread.
     61  [[nodiscard]] static bool HasCurrentDefault();
     62 
     63  class CurrentHandleOverride;
     64  class CurrentHandleOverrideForTesting;
     65 
     66  class BASE_EXPORT CurrentDefaultHandle {
     67   public:
     68    // Binds |task_runner| to the current thread. |task_runner| must belong
     69    // to the current thread.
     70    explicit CurrentDefaultHandle(
     71        scoped_refptr<SingleThreadTaskRunner> task_runner);
     72 
     73    CurrentDefaultHandle(const CurrentDefaultHandle&) = delete;
     74    CurrentDefaultHandle& operator=(const CurrentDefaultHandle&) = delete;
     75 
     76    ~CurrentDefaultHandle();
     77 
     78   private:
     79    friend class SingleThreadTaskRunner;
     80    friend class CurrentHandleOverride;
     81 
     82    const AutoReset<CurrentDefaultHandle*> resetter_;
     83 
     84    scoped_refptr<SingleThreadTaskRunner> task_runner_;
     85 
     86    // Registers |task_runner_|'s SequencedTaskRunner interface as the
     87    // SequencedTaskRunner::CurrentDefaultHandle on this thread.
     88    SequencedTaskRunner::CurrentDefaultHandle
     89        sequenced_task_runner_current_default_;
     90  };
     91 
     92  // CurrentHandleOverride overrides the task runner returned by
     93  // |SingleThreadTaskRunner::GetCurrentDefault()| to point at
     94  // |overriding_task_runner| until the |CurrentHandleOverride| goes out of
     95  // scope. CurrentHandleOverride instantiates a new SingleThreadTaskRunner if
     96  // SingleThreadTaskRunner is not instantiated on the current thread. Nested
     97  // overrides are allowed but callers must ensure the |CurrentHandleOverride|s
     98  // expire in LIFO (stack) order.
     99  //
    100  // Note: nesting SingleThreadTaskRunner is subtle and should be done with
    101  // care, hence the need to friend and request a //base/OWNERS review for usage
    102  // outside of tests. Use CurrentHandleOverrideForTesting to bypass the friend
    103  // requirement in tests.
    104  class BASE_EXPORT CurrentHandleOverride {
    105   public:
    106    CurrentHandleOverride(const CurrentHandleOverride&) = delete;
    107    CurrentHandleOverride& operator=(const CurrentHandleOverride&) = delete;
    108    ~CurrentHandleOverride();
    109 
    110   private:
    111    friend class CurrentHandleOverrideForTesting;
    112    FRIEND_TEST_ALL_PREFIXES(SingleThreadTaskRunnerCurrentDefaultHandleTest,
    113                             NestedRunLoop);
    114 
    115    // We expect SingleThreadTaskRunner::CurrentHandleOverride to be only needed
    116    // under special circumstances. Require them to be enumerated as friends to
    117    // require //base/OWNERS review. Use
    118    // SingleThreadTaskRunner::CurrentHandleOverrideForTesting in unit tests to
    119    // avoid the friend requirement.
    120 
    121    friend class blink::scheduler::MainThreadSchedulerImpl;
    122 
    123    // Constructs a SingleThreadTaskRunner::CurrentHandleOverride which will
    124    // make SingleThreadTaskRunner::GetCurrentDefault() return
    125    // |overriding_task_runner| for its lifetime. |allow_nested_loop| specifies
    126    // whether RunLoop::Run() is allowed during this override's lifetime. It's
    127    // not recommended to allow this unless the current thread's scheduler
    128    // guarantees that only tasks which pertain to |overriding_task_runner|'s
    129    // context will be run by nested RunLoops.
    130    explicit CurrentHandleOverride(
    131        scoped_refptr<SingleThreadTaskRunner> overriding_task_runner,
    132        bool allow_nested_runloop = false);
    133 
    134    absl::optional<SingleThreadTaskRunner::CurrentDefaultHandle>
    135        top_level_thread_task_runner_current_default_;
    136 
    137    scoped_refptr<SingleThreadTaskRunner> task_runner_to_restore_;
    138 
    139 #if DCHECK_IS_ON()
    140    // This field is not a raw_ptr<> because it was filtered by the rewriter
    141    // for: #union
    142    RAW_PTR_EXCLUSION SingleThreadTaskRunner*
    143        expected_task_runner_before_restore_{nullptr};
    144 #endif
    145 
    146    std::unique_ptr<ScopedDisallowRunningRunLoop> no_running_during_override_;
    147  };
    148 
    149  // Note: nesting CurrentHandleOverrides isn't generally desired but it's
    150  // useful in some unit tests where multiple task runners share the main thread
    151  // for simplicity and determinism. Only use this when no other constructs will
    152  // work (see base/test/task_environment.h and
    153  // base/test/test_mock_time_task_runner.h for preferred alternatives).
    154  class BASE_EXPORT CurrentHandleOverrideForTesting {
    155   public:
    156    explicit CurrentHandleOverrideForTesting(
    157        scoped_refptr<SingleThreadTaskRunner> overriding_task_runner)
    158        : thread_task_runner_current_override_(
    159              std::move(overriding_task_runner)) {}
    160 
    161   private:
    162    CurrentHandleOverride thread_task_runner_current_override_;
    163  };
    164 
    165 protected:
    166  ~SingleThreadTaskRunner() override = default;
    167 };
    168 
    169 }  // namespace base
    170 
    171 #endif  // BASE_TASK_SINGLE_THREAD_TASK_RUNNER_H_