xref: /aosp_15_r20/external/cronet/base/task/sequence_manager/thread_controller_impl.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 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_SEQUENCE_MANAGER_THREAD_CONTROLLER_IMPL_H_
6 #define BASE_TASK_SEQUENCE_MANAGER_THREAD_CONTROLLER_IMPL_H_
7 
8 #include <memory>
9 
10 #include "base/base_export.h"
11 #include "base/cancelable_callback.h"
12 #include "base/dcheck_is_on.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/run_loop.h"
16 #include "base/sequence_checker.h"
17 #include "base/task/common/task_annotator.h"
18 #include "base/task/sequence_manager/thread_controller.h"
19 #include "base/task/sequence_manager/work_deduplicator.h"
20 #include "base/task/single_thread_task_runner.h"
21 #include "build/build_config.h"
22 
23 namespace base {
24 namespace sequence_manager {
25 namespace internal {
26 class SequenceManagerImpl;
27 
28 // This is the interface between a SequenceManager which sits on top of an
29 // underlying SequenceManagerImpl or SingleThreadTaskRunner. Currently it's only
30 // used for workers in blink although we'd intend to migrate those to
31 // ThreadControllerWithMessagePumpImpl (https://crbug.com/948051). Long term we
32 // intend to use this for sequence funneling.
33 class BASE_EXPORT ThreadControllerImpl : public ThreadController,
34                                          public RunLoop::NestingObserver {
35  public:
36   ThreadControllerImpl(const ThreadControllerImpl&) = delete;
37   ThreadControllerImpl& operator=(const ThreadControllerImpl&) = delete;
38   ~ThreadControllerImpl() override;
39 
40   // TODO(https://crbug.com/948051): replace |funneled_sequence_manager| with
41   // |funneled_task_runner| when we sort out the workers
42   static std::unique_ptr<ThreadControllerImpl> Create(
43       SequenceManagerImpl* funneled_sequence_manager,
44       const TickClock* time_source);
45 
46   // ThreadController:
47   void SetWorkBatchSize(int work_batch_size) override;
48   void WillQueueTask(PendingTask* pending_task) override;
49   void ScheduleWork() override;
50   void BindToCurrentThread(std::unique_ptr<MessagePump> message_pump) override;
51   void SetNextDelayedDoWork(LazyNow* lazy_now,
52                             std::optional<WakeUp> wake_up) override;
53   void SetSequencedTaskSource(SequencedTaskSource* sequence) override;
54   bool RunsTasksInCurrentSequence() override;
55   void SetDefaultTaskRunner(scoped_refptr<SingleThreadTaskRunner>) override;
56   scoped_refptr<SingleThreadTaskRunner> GetDefaultTaskRunner() override;
57   void RestoreDefaultTaskRunner() override;
58   void AddNestingObserver(RunLoop::NestingObserver* observer) override;
59   void RemoveNestingObserver(RunLoop::NestingObserver* observer) override;
60   void SetTaskExecutionAllowedInNativeNestedLoop(bool allowed) override;
61   bool IsTaskExecutionAllowed() const override;
62   MessagePump* GetBoundMessagePump() const override;
63 #if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
64   void AttachToMessagePump() override;
65 #endif
66 #if BUILDFLAG(IS_IOS)
67   void DetachFromMessagePump() override;
68 #endif
69   void PrioritizeYieldingToNative(base::TimeTicks prioritize_until) override;
70   bool ShouldQuitRunLoopWhenIdle() override;
71 
72   // RunLoop::NestingObserver:
73   void OnBeginNestedRunLoop() override;
74   void OnExitNestedRunLoop() override;
75 
76  protected:
77   ThreadControllerImpl(SequenceManagerImpl* sequence_manager,
78                        scoped_refptr<SingleThreadTaskRunner> task_runner,
79                        const TickClock* time_source);
80 
81   const raw_ptr<SequenceManagerImpl> funneled_sequence_manager_;
82   const scoped_refptr<SingleThreadTaskRunner> task_runner_;
83 
84   raw_ptr<RunLoop::NestingObserver> nesting_observer_ = nullptr;
85 
86  private:
87   enum class WorkType { kImmediate, kDelayed };
88 
89   void DoWork(WorkType work_type);
90 
91   // TODO(scheduler-dev): Maybe fold this into the main class and use
92   // thread annotations.
93   struct MainSequenceOnly {
94     MainSequenceOnly();
95     ~MainSequenceOnly();
96 
97     int work_batch_size_ = 1;
98 
99     TimeTicks next_delayed_do_work = TimeTicks::Max();
100   };
101 
102   MainSequenceOnly main_sequence_only_;
main_sequence_only()103   MainSequenceOnly& main_sequence_only() {
104     DCHECK_CALLED_ON_VALID_SEQUENCE(associated_thread_->sequence_checker);
105     return main_sequence_only_;
106   }
main_sequence_only()107   const MainSequenceOnly& main_sequence_only() const {
108     DCHECK_CALLED_ON_VALID_SEQUENCE(associated_thread_->sequence_checker);
109     return main_sequence_only_;
110   }
111 
112   scoped_refptr<SingleThreadTaskRunner> message_loop_task_runner_;
113   RepeatingClosure immediate_do_work_closure_;
114   RepeatingClosure delayed_do_work_closure_;
115   CancelableRepeatingClosure cancelable_delayed_do_work_closure_;
116   raw_ptr<SequencedTaskSource> sequence_ = nullptr;  // Not owned.
117   TaskAnnotator task_annotator_;
118   WorkDeduplicator work_deduplicator_;
119 
120 #if DCHECK_IS_ON()
121   bool default_task_runner_set_ = false;
122 #endif
123 
124   WeakPtrFactory<ThreadControllerImpl> weak_factory_{this};
125 };
126 
127 }  // namespace internal
128 }  // namespace sequence_manager
129 }  // namespace base
130 
131 #endif  // BASE_TASK_SEQUENCE_MANAGER_THREAD_CONTROLLER_IMPL_H_
132