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