1 // Copyright 2018 The Chromium Authors. All rights reserved. 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_WITH_MESSAGE_PUMP_IMPL_H_ 6 #define BASE_TASK_SEQUENCE_MANAGER_THREAD_CONTROLLER_WITH_MESSAGE_PUMP_IMPL_H_ 7 8 #include "base/debug/task_annotator.h" 9 #include "base/message_loop/message_pump.h" 10 #include "base/task/sequence_manager/sequenced_task_source.h" 11 #include "base/task/sequence_manager/thread_controller.h" 12 #include "base/threading/platform_thread.h" 13 #include "base/threading/thread_task_runner_handle.h" 14 15 namespace base { 16 namespace sequence_manager { 17 namespace internal { 18 19 // EXPERIMENTAL ThreadController implementation which doesn't use 20 // MessageLoop or a task runner to schedule their DoWork calls. 21 // See https://crbug.com/828835. 22 class BASE_EXPORT ThreadControllerWithMessagePumpImpl 23 : public ThreadController, 24 public MessagePump::Delegate, 25 public RunLoop::Delegate { 26 public: 27 explicit ThreadControllerWithMessagePumpImpl(TickClock* time_source); 28 ~ThreadControllerWithMessagePumpImpl() override; 29 30 // ThreadController implementation: 31 void SetSequencedTaskSource(SequencedTaskSource* task_source) override; 32 void SetWorkBatchSize(int work_batch_size) override; 33 void WillQueueTask(PendingTask* pending_task) override; 34 void ScheduleWork() override; 35 void SetNextDelayedDoWork(LazyNow* lazy_now, TimeTicks run_time) override; 36 const TickClock* GetClock() override; 37 bool RunsTasksInCurrentSequence() override; 38 void SetDefaultTaskRunner( 39 scoped_refptr<SingleThreadTaskRunner> task_runner) override; 40 void RestoreDefaultTaskRunner() override; 41 void AddNestingObserver(RunLoop::NestingObserver* observer) override; 42 void RemoveNestingObserver(RunLoop::NestingObserver* observer) override; 43 44 private: 45 friend class DoWorkScope; 46 friend class RunScope; 47 48 // MessagePump::Delegate implementation. 49 bool DoWork() override; 50 bool DoDelayedWork(TimeTicks* next_run_time) override; 51 bool DoIdleWork() override; 52 53 // RunLoop::Delegate implementation. 54 void Run(bool application_tasks_allowed) override; 55 void Quit() override; 56 void EnsureWorkScheduled() override; 57 58 struct MainThreadOnly { 59 MainThreadOnly(); 60 ~MainThreadOnly(); 61 62 SequencedTaskSource* task_source = nullptr; // Not owned. 63 RunLoop::NestingObserver* nesting_observer = nullptr; // Not owned. 64 std::unique_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle; 65 66 // Next delayed DoWork time for scheduling de-duplication purpose. 67 TimeTicks next_delayed_work; 68 69 // Indicates that we should yield DoWork ASAP. 70 bool quit_do_work = false; 71 72 // Number of tasks processed in a single DoWork invocation. 73 int batch_size = 1; 74 75 // Number of RunLoop layers currently running. 76 int run_depth = 0; 77 78 // Number of DoWork running, but only the inner-most one can take tasks. 79 // Must be equal to |run_depth| or |run_depth - 1|. 80 int do_work_depth = 0; 81 }; 82 main_thread_only()83 MainThreadOnly& main_thread_only() { 84 DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); 85 return main_thread_only_; 86 } 87 88 // Returns true if there's a DoWork running on the inner-most nesting layer. is_doing_work()89 bool is_doing_work() const { 90 DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); 91 return main_thread_only_.do_work_depth == main_thread_only_.run_depth && 92 main_thread_only_.do_work_depth != 0; 93 } 94 95 MainThreadOnly main_thread_only_; 96 const PlatformThreadId main_thread_id_; 97 std::unique_ptr<MessagePump> pump_; 98 debug::TaskAnnotator task_annotator_; 99 TickClock* time_source_; // Not owned. 100 101 THREAD_CHECKER(main_thread_checker_); 102 DISALLOW_COPY_AND_ASSIGN(ThreadControllerWithMessagePumpImpl); 103 }; 104 105 } // namespace internal 106 } // namespace sequence_manager 107 } // namespace base 108 109 #endif // BASE_TASK_SEQUENCE_MANAGER_THREAD_CONTROLLER_WITH_MESSAGE_PUMP_IMPL_H_ 110