blob: 2f75ebf9f921d78caab9ab5a5611fde6c607ffbb [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2018 The Chromium Authors
Alex Clarke7dc412d2018-09-14 10:02:312// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_EXECUTOR_H_
6#define CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_EXECUTOR_H_
7
Alex Clarke4779e4bd2019-02-15 22:32:038#include <memory>
9
Eric Seckler0618f402018-10-29 12:08:5210#include "base/memory/scoped_refptr.h"
Sean Mahere672a662023-01-09 21:42:2811#include "base/task/sequenced_task_runner.h"
12#include "base/task/single_thread_task_runner.h"
Alex Clarke7dc412d2018-09-14 10:02:3113#include "build/build_config.h"
Gabriel Charette748577aa2019-08-12 12:53:5514#include "content/browser/scheduler/browser_io_thread_delegate.h"
Carlos Caballero5f6212b2019-05-13 13:45:1615#include "content/browser/scheduler/browser_ui_thread_scheduler.h"
Alex Clarke7dc412d2018-09-14 10:02:3116#include "content/common/content_export.h"
Eric Seckler501f9a12018-09-14 18:09:4417#include "content/public/browser/browser_task_traits.h"
Carlos Caballeroff8c5032019-04-01 11:15:0818#include "content/public/browser/browser_thread.h"
Alex Clarke7dc412d2018-09-14 10:02:3119
20namespace content {
21
John Abd-El-Malekf3243dc2021-05-07 16:20:0122class BrowserProcessIOThread;
Alex Clarke831ed1e62019-02-18 21:10:0823
Chidera Olibie0edf0e42025-01-21 12:18:1624// The BrowserTaskExecutor's job is to map base::TaskTraits to actual task
25// queues for the browser process.
26class CONTENT_EXPORT BrowserTaskExecutor {
Alex Clarkebbf891dc2019-10-09 14:18:0227 public:
Chidera Olibie0edf0e42025-01-21 12:18:1628 // Creates and registers a BrowserTaskExecutor on the current thread which
29 // owns a BrowserUIThreadScheduler. This facilitates posting tasks to a
30 // BrowserThread via //base/task/post_task.h.
31 // TODO(crbug.com/40108370): Clean this up now that post_task.h is deprecated.
Chidera Olibiedebdc542025-03-25 23:14:0832 // By default, BrowserThread::UI task queues except best effort ones are also
33 // enabled. The ContentBrowserClient may decide to defer enabling the task
34 // queues.
Chidera Olibie0edf0e42025-01-21 12:18:1635 // TODO(carlscab): These queues should be enabled in
36 // BrowserMainLoop::InitializeMainThread() but some Android tests fail if we
37 // do so.
38 static void Create();
39
40 BrowserTaskExecutor(const BrowserTaskExecutor&) = delete;
41 BrowserTaskExecutor& operator=(const BrowserTaskExecutor&) = delete;
Alex Clarkebbf891dc2019-10-09 14:18:0242
Gabriel Charette49e3cd02020-01-28 03:45:2743 // Returns the task runner for |traits| under |identifier|. Note: during the
44 // migration away from task traits extension, |traits| may also contain a
45 // browser thread id, if so, it should match |identifier| (|identifier| has to
46 // be provided explicitly because in the new source of tasks it's not part of
47 // |traits|) -- ref. crbug.com/1026641.
48 scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(
49 BrowserThread::ID identifier,
Michael Thiessen44c306f82023-04-06 12:42:1750 const BrowserTaskTraits& traits) const;
Alex Clarkebbf891dc2019-10-09 14:18:0251
Gabriel Charette49e3cd02020-01-28 03:45:2752 // Helper to match a QueueType from TaskTraits.
Alison Gale770f3fc2024-04-27 00:39:5853 // TODO(crbug.com/40108370): Take BrowserTaskTraits as a parameter when
54 // getting off the need to support base::TaskTraits currently passed to this
55 // class in its role as a base::TaskExecutor.
Michael Thiessen44c306f82023-04-06 12:42:1756 static BrowserTaskQueues::QueueType GetQueueType(
57 const BrowserTaskTraits& traits);
Gabriel Charette49e3cd02020-01-28 03:45:2758
Carlos Caballeroe840fc32019-05-27 14:16:3759 // Creates the IO thread using the scheduling infrastructure set up in the
60 // Create() method. That means that clients have access to TaskRunners
61 // associated with the IO thread before that thread is even created. In order
Gabriel Charette18110512019-08-15 15:27:0562 // to do so this class will own the Thread::Delegate for the IO thread
63 // (BrowserIOThreadDelegate) until the thread is created, at which point
64 // ownership will be transferred and the |BrowserTaskExecutor| will only
65 // communicate with it via TaskRunner instances.
Carlos Caballeroe840fc32019-05-27 14:16:3766 //
67 // Browser task queues will initially be disabled, that is tasks posted to
68 // them will not run. But the default task runner of the thread (the one you
Sean Maher70f2942932023-01-04 22:15:0669 // get via SingleThreadTaskRunner::GetCurrentDefault()) will be active. This
70 // is the same task runner you get by calling
71 // BrowserProcessIOThread::task_runner(). The queues can be initialized by
72 // calling InitializeIOThread which is done during Chromium startup in
73 // BrowserMainLoop::CreateThreads.
Carlos Caballeroe840fc32019-05-27 14:16:3774 //
75 // Early on during Chromium startup we initialize the ServiceManager and it
76 // needs to run tasks immediately. The ServiceManager itself does not know
77 // about the IO thread (it does not use the browser task traits), it only uses
78 // the task runner provided to it during initialization and possibly
Sean Maher70f2942932023-01-04 22:15:0679 // SingleThreadTaskRunner::GetCurrentDefault() from tasks it posts. But we
80 // currently run it on the IO thread so we need the default task runner to be
81 // active for its tasks to run. Note that since tasks posted via the browser
82 // task traits will not run they won't be able to access the default task
83 // runner either, so for those tasks the default task queue is also
84 // "disabled".
Carlos Caballeroe840fc32019-05-27 14:16:3785 //
86 // Attention: This method can only be called once (as there must be only one
87 // IO thread).
Carlos Caballerobdb30702019-07-31 08:08:2888 // Attention: Must be called after Create()
89 // Attention: Can not be called after Shutdown() or ResetForTesting()
John Abd-El-Malekf3243dc2021-05-07 16:20:0190 static std::unique_ptr<BrowserProcessIOThread> CreateIOThread();
Carlos Caballeroe840fc32019-05-27 14:16:3791
92 // Enables non best effort queues on the IO thread. Usually called from
93 // BrowserMainLoop::CreateThreads.
94 static void InitializeIOThread();
95
Minoru Chikamunea0317562022-03-22 15:30:2196 // Informs BrowserTaskExecutor that startup is complete.
97 // It will communicate that to UI and IO thread BrowserTaskQueues.
Carlos Caballero72e8a202019-05-21 16:51:1798 // Can be called multiple times.
Minoru Chikamunea0317562022-03-22 15:30:2199 static void OnStartupComplete();
Carlos Caballero72e8a202019-05-21 16:51:17100
Gabriel Charette49e3cd02020-01-28 03:45:27101 // Helpers to statically call into BaseBrowserTaskExecutor::GetTaskRunner()
102 // from browser_thread_impl.cc. Callers should use browser_thread.h's
103 // GetUIThreadTaskRunner over this.
Alison Gale770f3fc2024-04-27 00:39:58104 // TODO(crbug.com/40108370): Clean up this indirection after the migration
105 // (once registering a base::BrowserTaskExecutor is no longer necessary).
Gabriel Charette49e3cd02020-01-28 03:45:27106 static scoped_refptr<base::SingleThreadTaskRunner> GetUIThreadTaskRunner(
107 const BrowserTaskTraits& traits);
108 static scoped_refptr<base::SingleThreadTaskRunner> GetIOThreadTaskRunner(
109 const BrowserTaskTraits& traits);
110
Michael Thiessen7f5dfb92023-03-30 16:50:21111 // As Create but with the user provided objects.
Carlos Caballeroe840fc32019-05-27 14:16:37112 static void CreateForTesting(
113 std::unique_ptr<BrowserUIThreadScheduler> browser_ui_thread_scheduler,
Gabriel Charette748577aa2019-08-12 12:53:55114 std::unique_ptr<BrowserIOThreadDelegate> browser_io_thread_delegate);
Alex Clarke4779e4bd2019-02-15 22:32:03115
mikt541ac712025-08-04 03:16:22116 // This must be called after the FeatureList has been initialized in order
117 // for scheduling experiments to function.
118 static void InstallPartitionAllocSchedulerLoopQuarantineTaskObserver();
119
Alex Clarke4779e4bd2019-02-15 22:32:03120 // Winds down the BrowserTaskExecutor, after this no tasks can be executed
121 // and the base::TaskExecutor APIs are non-functional but won't crash if
Carlos Caballerobdb30702019-07-31 08:08:28122 // called. In unittests however we need to clean up, so
123 // BrowserTaskExecutor::ResetForTesting should be
Gabriel Charette798fde72019-08-20 22:24:04124 // called (~BrowserTaskEnvironment() takes care of this).
Alex Clarke4779e4bd2019-02-15 22:32:03125 static void Shutdown();
126
Alex Clarke7dc412d2018-09-14 10:02:31127 // Unregister and delete the TaskExecutor after a test.
128 static void ResetForTesting();
129
Carlos Caballeroff8c5032019-04-01 11:15:08130 // Runs all pending tasks for the given thread. Tasks posted after this method
131 // is called (in particular any task posted from within any of the pending
132 // tasks) will be queued but not run. Conceptually this call will disable all
133 // queues, run any pending tasks, and re-enable all the queues.
134 //
135 // If any of the pending tasks posted a task, these could be run by calling
136 // this method again or running a regular RunLoop. But if that were the case
137 // you should probably rewrite you tests to wait for a specific event instead.
Carlos Caballeroff8c5032019-04-01 11:15:08138 static void RunAllPendingTasksOnThreadForTesting(
139 BrowserThread::ID identifier);
140
Alex Clarke7dc412d2018-09-14 10:02:31141 private:
Chidera Olibiedebdc542025-03-25 23:14:08142 FRIEND_TEST_ALL_PREFIXES(BrowserTaskExecutorWithCustomSchedulerTest,
143 OnlyDefaultTaskRunnerActiveAfterCreationForIO);
Karolina Soltysb083f932019-09-25 16:18:06144 friend class BrowserIOThreadDelegate;
Alex Clarkebbf891dc2019-10-09 14:18:02145
Carlos Caballeroe840fc32019-05-27 14:16:37146 static void CreateInternal(
147 std::unique_ptr<BrowserUIThreadScheduler> browser_ui_thread_scheduler,
Gabriel Charette748577aa2019-08-12 12:53:55148 std::unique_ptr<BrowserIOThreadDelegate> browser_io_thread_delegate);
Carlos Caballeroe840fc32019-05-27 14:16:37149
Alex Clarke831ed1e62019-02-18 21:10:08150 explicit BrowserTaskExecutor(
Carlos Caballeroe840fc32019-05-27 14:16:37151 std::unique_ptr<BrowserUIThreadScheduler> browser_ui_thread_scheduler,
Gabriel Charette748577aa2019-08-12 12:53:55152 std::unique_ptr<BrowserIOThreadDelegate> browser_io_thread_delegate);
Chidera Olibie0edf0e42025-01-21 12:18:16153 ~BrowserTaskExecutor();
Alex Clarke7dc412d2018-09-14 10:02:31154
Karolina Soltysb083f932019-09-25 16:18:06155 static BrowserTaskExecutor* Get();
156
Chidera Olibie0edf0e42025-01-21 12:18:16157 std::unique_ptr<BrowserUIThreadScheduler> browser_ui_thread_scheduler_;
158 scoped_refptr<BrowserUIThreadScheduler::Handle> browser_ui_thread_handle_;
159
160 std::unique_ptr<BrowserIOThreadDelegate> browser_io_thread_delegate_;
161 scoped_refptr<BrowserIOThreadDelegate::Handle> browser_io_thread_handle_;
Alex Clarke7dc412d2018-09-14 10:02:31162};
163
164} // namespace content
165
166#endif // CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_EXECUTOR_H_