• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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