fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 1 | // Copyright 2016 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_SCHEDULER_TASK_SCHEDULER_H_ |
| 6 | #define BASE_TASK_SCHEDULER_TASK_SCHEDULER_H_ |
| 7 | |
| 8 | #include <memory> |
robliao | d2ab1f7 | 2016-08-02 20:51:49 | [diff] [blame] | 9 | #include <vector> |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 10 | |
| 11 | #include "base/base_export.h" |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 12 | #include "base/callback.h" |
Francois Doray | 6d3c64969 | 2017-06-16 19:20:25 | [diff] [blame] | 13 | #include "base/gtest_prod_util.h" |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 14 | #include "base/memory/ref_counted.h" |
fdoray | e72adfa1 | 2016-11-02 14:35:26 | [diff] [blame] | 15 | #include "base/sequenced_task_runner.h" |
| 16 | #include "base/single_thread_task_runner.h" |
fdoray | 5d16e80 | 2017-04-19 14:45:16 | [diff] [blame] | 17 | #include "base/strings/string_piece.h" |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 18 | #include "base/task_runner.h" |
fdoray | 3f6f57a4 | 2017-03-28 18:02:39 | [diff] [blame] | 19 | #include "base/task_scheduler/scheduler_worker_pool_params.h" |
robliao | 94520d7 | 2017-05-12 12:43:35 | [diff] [blame] | 20 | #include "base/task_scheduler/single_thread_task_runner_thread_mode.h" |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 21 | #include "base/task_scheduler/task_traits.h" |
fdoray | 45cc9079 | 2017-01-05 19:24:31 | [diff] [blame] | 22 | #include "base/time/time.h" |
robliao | 75dd50b | 2017-03-29 17:11:17 | [diff] [blame] | 23 | #include "build/build_config.h" |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 24 | |
fdoray | 1028b07d | 2017-01-31 20:36:14 | [diff] [blame] | 25 | namespace gin { |
Andreas Haas | c13cae8 | 2017-11-16 12:54:38 | [diff] [blame^] | 26 | class V8BackgroundTaskRunner; |
fdoray | 1028b07d | 2017-01-31 20:36:14 | [diff] [blame] | 27 | } |
| 28 | |
Francois Doray | 6d3c64969 | 2017-06-16 19:20:25 | [diff] [blame] | 29 | namespace content { |
| 30 | // Can't use the FRIEND_TEST_ALL_PREFIXES macro because the test is in a |
| 31 | // different namespace. |
| 32 | class BrowserMainLoopTest_CreateThreadsInSingleProcess_Test; |
| 33 | } // namespace content |
| 34 | |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 35 | namespace base { |
| 36 | |
robliao | 6f59a9a | 2016-10-20 17:26:14 | [diff] [blame] | 37 | class HistogramBase; |
Brett Wilson | abbb960 | 2017-09-11 23:26:39 | [diff] [blame] | 38 | class Location; |
robliao | d2ab1f7 | 2016-08-02 20:51:49 | [diff] [blame] | 39 | |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 40 | // Interface for a task scheduler and static methods to manage the instance used |
fdoray | 0f358ee | 2017-04-25 21:22:23 | [diff] [blame] | 41 | // by the post_task.h API. |
| 42 | // |
| 43 | // The task scheduler doesn't create threads until Start() is called. Tasks can |
| 44 | // be posted at any time but will not run until after Start() is called. |
| 45 | // |
| 46 | // The instance methods of this class are thread-safe. |
| 47 | // |
| 48 | // Note: All base/task_scheduler users should go through post_task.h instead of |
| 49 | // TaskScheduler except for the one callsite per process which manages the |
| 50 | // process's instance. |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 51 | class BASE_EXPORT TaskScheduler { |
| 52 | public: |
fdoray | 3f6f57a4 | 2017-03-28 18:02:39 | [diff] [blame] | 53 | struct BASE_EXPORT InitParams { |
Robert Liao | 4393dc6 | 2017-11-01 20:06:03 | [diff] [blame] | 54 | enum class SharedWorkerPoolEnvironment { |
| 55 | // Use the default environment (no environment). |
| 56 | DEFAULT, |
| 57 | #if defined(OS_WIN) |
| 58 | // Place the worker in a COM MTA. |
| 59 | COM_MTA, |
| 60 | #endif // defined(OS_WIN) |
| 61 | }; |
| 62 | |
fdoray | 3f6f57a4 | 2017-03-28 18:02:39 | [diff] [blame] | 63 | InitParams( |
| 64 | const SchedulerWorkerPoolParams& background_worker_pool_params_in, |
| 65 | const SchedulerWorkerPoolParams& |
| 66 | background_blocking_worker_pool_params_in, |
| 67 | const SchedulerWorkerPoolParams& foreground_worker_pool_params_in, |
| 68 | const SchedulerWorkerPoolParams& |
Robert Liao | 4393dc6 | 2017-11-01 20:06:03 | [diff] [blame] | 69 | foreground_blocking_worker_pool_params_in, |
| 70 | SharedWorkerPoolEnvironment shared_worker_pool_environment_in = |
| 71 | SharedWorkerPoolEnvironment::DEFAULT); |
fdoray | 3f6f57a4 | 2017-03-28 18:02:39 | [diff] [blame] | 72 | ~InitParams(); |
| 73 | |
Francois Doray | 6d3c64969 | 2017-06-16 19:20:25 | [diff] [blame] | 74 | SchedulerWorkerPoolParams background_worker_pool_params; |
| 75 | SchedulerWorkerPoolParams background_blocking_worker_pool_params; |
| 76 | SchedulerWorkerPoolParams foreground_worker_pool_params; |
| 77 | SchedulerWorkerPoolParams foreground_blocking_worker_pool_params; |
Robert Liao | 4393dc6 | 2017-11-01 20:06:03 | [diff] [blame] | 78 | SharedWorkerPoolEnvironment shared_worker_pool_environment; |
fdoray | 3f6f57a4 | 2017-03-28 18:02:39 | [diff] [blame] | 79 | }; |
| 80 | |
fdoray | 7bba05e | 2017-01-25 02:34:45 | [diff] [blame] | 81 | // Destroying a TaskScheduler is not allowed in production; it is always |
| 82 | // leaked. In tests, it should only be destroyed after JoinForTesting() has |
| 83 | // returned. |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 84 | virtual ~TaskScheduler() = default; |
| 85 | |
fdoray | 0f358ee | 2017-04-25 21:22:23 | [diff] [blame] | 86 | // Allows the task scheduler to create threads and run tasks following the |
| 87 | // |init_params| specification. CHECKs on failure. |
| 88 | virtual void Start(const InitParams& init_params) = 0; |
| 89 | |
fdoray | 45cc9079 | 2017-01-05 19:24:31 | [diff] [blame] | 90 | // Posts |task| with a |delay| and specific |traits|. |delay| can be zero. |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 91 | // For one off tasks that don't require a TaskRunner. |
Brett Wilson | abbb960 | 2017-09-11 23:26:39 | [diff] [blame] | 92 | virtual void PostDelayedTaskWithTraits(const Location& from_here, |
| 93 | const TaskTraits& traits, |
| 94 | OnceClosure task, |
| 95 | TimeDelta delay) = 0; |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 96 | |
fdoray | e72adfa1 | 2016-11-02 14:35:26 | [diff] [blame] | 97 | // Returns a TaskRunner whose PostTask invocations result in scheduling tasks |
| 98 | // using |traits|. Tasks may run in any order and in parallel. |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 99 | virtual scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits( |
fdoray | e72adfa1 | 2016-11-02 14:35:26 | [diff] [blame] | 100 | const TaskTraits& traits) = 0; |
| 101 | |
| 102 | // Returns a SequencedTaskRunner whose PostTask invocations result in |
| 103 | // scheduling tasks using |traits|. Tasks run one at a time in posting order. |
| 104 | virtual scoped_refptr<SequencedTaskRunner> |
| 105 | CreateSequencedTaskRunnerWithTraits(const TaskTraits& traits) = 0; |
| 106 | |
| 107 | // Returns a SingleThreadTaskRunner whose PostTask invocations result in |
| 108 | // scheduling tasks using |traits|. Tasks run on a single thread in posting |
| 109 | // order. |
| 110 | virtual scoped_refptr<SingleThreadTaskRunner> |
robliao | 94520d7 | 2017-05-12 12:43:35 | [diff] [blame] | 111 | CreateSingleThreadTaskRunnerWithTraits( |
| 112 | const TaskTraits& traits, |
robliao | 0c09719 | 2017-05-16 13:56:37 | [diff] [blame] | 113 | SingleThreadTaskRunnerThreadMode thread_mode) = 0; |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 114 | |
robliao | 75dd50b | 2017-03-29 17:11:17 | [diff] [blame] | 115 | #if defined(OS_WIN) |
| 116 | // Returns a SingleThreadTaskRunner whose PostTask invocations result in |
| 117 | // scheduling tasks using |traits| in a COM Single-Threaded Apartment. Tasks |
| 118 | // run in the same Single-Threaded Apartment in posting order for the returned |
| 119 | // SingleThreadTaskRunner. There is not necessarily a one-to-one |
| 120 | // correspondence between SingleThreadTaskRunners and Single-Threaded |
| 121 | // Apartments. The implementation is free to share apartments or create new |
| 122 | // apartments as necessary. In either case, care should be taken to make sure |
| 123 | // COM pointers are not smuggled across apartments. |
| 124 | virtual scoped_refptr<SingleThreadTaskRunner> |
robliao | 94520d7 | 2017-05-12 12:43:35 | [diff] [blame] | 125 | CreateCOMSTATaskRunnerWithTraits( |
| 126 | const TaskTraits& traits, |
robliao | 0c09719 | 2017-05-16 13:56:37 | [diff] [blame] | 127 | SingleThreadTaskRunnerThreadMode thread_mode) = 0; |
robliao | 75dd50b | 2017-03-29 17:11:17 | [diff] [blame] | 128 | #endif // defined(OS_WIN) |
| 129 | |
robliao | 6f59a9a | 2016-10-20 17:26:14 | [diff] [blame] | 130 | // Returns a vector of all histograms available in this task scheduler. |
| 131 | virtual std::vector<const HistogramBase*> GetHistograms() const = 0; |
| 132 | |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 133 | // Synchronously shuts down the scheduler. Once this is called, only tasks |
| 134 | // posted with the BLOCK_SHUTDOWN behavior will be run. When this returns: |
| 135 | // - All SKIP_ON_SHUTDOWN tasks that were already running have completed their |
| 136 | // execution. |
| 137 | // - All posted BLOCK_SHUTDOWN tasks have completed their execution. |
| 138 | // - CONTINUE_ON_SHUTDOWN tasks might still be running. |
| 139 | // Note that an implementation can keep threads and other resources alive to |
| 140 | // support running CONTINUE_ON_SHUTDOWN after this returns. This can only be |
| 141 | // called once. |
| 142 | virtual void Shutdown() = 0; |
| 143 | |
fdoray | fe309b0 | 2016-09-26 16:18:58 | [diff] [blame] | 144 | // Waits until there are no pending undelayed tasks. May be called in tests |
| 145 | // to validate that a condition is met after all undelayed tasks have run. |
| 146 | // |
| 147 | // Does not wait for delayed tasks. Waits for undelayed tasks posted from |
| 148 | // other threads during the call. Returns immediately when shutdown completes. |
| 149 | virtual void FlushForTesting() = 0; |
| 150 | |
fdoray | 7bba05e | 2017-01-25 02:34:45 | [diff] [blame] | 151 | // Joins all threads. Tasks that are already running are allowed to complete |
robliao | dc6f621 | 2017-02-01 23:13:41 | [diff] [blame] | 152 | // their execution. This can only be called once. Using this task scheduler |
| 153 | // instance to create task runners or post tasks is not permitted during or |
| 154 | // after this call. |
fdoray | 7bba05e | 2017-01-25 02:34:45 | [diff] [blame] | 155 | virtual void JoinForTesting() = 0; |
| 156 | |
fdoray | 43ec6df | 2017-04-25 23:16:12 | [diff] [blame] | 157 | // CreateAndStartWithDefaultParams(), Create(), and SetInstance() register a |
| 158 | // TaskScheduler to handle tasks posted through the post_task.h API for this |
| 159 | // process. |
| 160 | // |
| 161 | // Processes that need to initialize TaskScheduler with custom params or that |
| 162 | // need to allow tasks to be posted before the TaskScheduler creates its |
| 163 | // threads should use Create() followed by Start(). Other processes can use |
| 164 | // CreateAndStartWithDefaultParams(). |
| 165 | // |
| 166 | // A registered TaskScheduler is only deleted when a new TaskScheduler is |
| 167 | // registered. The last registered TaskScheduler is leaked on shutdown. The |
| 168 | // methods below must not be called when TaskRunners created by a previous |
| 169 | // TaskScheduler are still alive. The methods are not thread-safe; proper |
| 170 | // synchronization is required to use the post_task.h API after registering a |
| 171 | // new TaskScheduler. |
robliao | d2ab1f7 | 2016-08-02 20:51:49 | [diff] [blame] | 172 | |
fdoray | dafc341 | 2017-03-21 17:19:29 | [diff] [blame] | 173 | #if !defined(OS_NACL) |
fdoray | 43ec6df | 2017-04-25 23:16:12 | [diff] [blame] | 174 | // Creates and starts a task scheduler using default params. |name| is used to |
fdoray | dafc341 | 2017-03-21 17:19:29 | [diff] [blame] | 175 | // label threads and histograms. It should identify the component that calls |
fdoray | 43ec6df | 2017-04-25 23:16:12 | [diff] [blame] | 176 | // this. Start() is called by this method; it is invalid to call it again |
| 177 | // afterwards. CHECKs on failure. For tests, prefer |
| 178 | // base::test::ScopedTaskEnvironment (ensures isolation). |
| 179 | static void CreateAndStartWithDefaultParams(StringPiece name); |
Gabriel Charette | 3a32d46 | 2017-09-21 02:26:13 | [diff] [blame] | 180 | |
| 181 | // Same as CreateAndStartWithDefaultParams() but allows callers to split the |
| 182 | // Create() and StartWithDefaultParams() calls. |
| 183 | void StartWithDefaultParams(); |
fdoray | dafc341 | 2017-03-21 17:19:29 | [diff] [blame] | 184 | #endif // !defined(OS_NACL) |
fdoray | 9c7db371 | 2016-11-18 17:10:53 | [diff] [blame] | 185 | |
fdoray | 43ec6df | 2017-04-25 23:16:12 | [diff] [blame] | 186 | // Creates a ready to start task scheduler. |name| is used to label threads |
| 187 | // and histograms. It should identify the component that creates the |
| 188 | // TaskScheduler. The task scheduler doesn't create threads until Start() is |
| 189 | // called. Tasks can be posted at any time but will not run until after |
| 190 | // Start() is called. For tests, prefer base::test::ScopedTaskEnvironment |
fdoray | 3f6f57a4 | 2017-03-28 18:02:39 | [diff] [blame] | 191 | // (ensures isolation). |
fdoray | 43ec6df | 2017-04-25 23:16:12 | [diff] [blame] | 192 | static void Create(StringPiece name); |
| 193 | |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 194 | // Registers |task_scheduler| to handle tasks posted through the post_task.h |
Francois Doray | c4c3f64 | 2017-08-04 14:56:22 | [diff] [blame] | 195 | // API for this process. For tests, prefer base::test::ScopedTaskEnvironment |
gab | 4fe88c1e | 2017-02-24 18:10:46 | [diff] [blame] | 196 | // (ensures isolation). |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 197 | static void SetInstance(std::unique_ptr<TaskScheduler> task_scheduler); |
| 198 | |
gab | 4fe88c1e | 2017-02-24 18:10:46 | [diff] [blame] | 199 | // Retrieve the TaskScheduler set via SetInstance() or |
| 200 | // CreateAndSet(Simple|Default)TaskScheduler(). This should be used very |
| 201 | // rarely; most users of TaskScheduler should use the post_task.h API. In |
| 202 | // particular, refrain from doing |
| 203 | // if (!TaskScheduler::GetInstance()) { |
| 204 | // TaskScheduler::SetInstance(...); |
| 205 | // base::PostTask(...); |
| 206 | // } |
| 207 | // instead make sure to SetInstance() early in one determinstic place in the |
| 208 | // process' initialization phase. |
| 209 | // In doubt, consult with //base/task_scheduler/OWNERS. |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 210 | static TaskScheduler* GetInstance(); |
fdoray | 1028b07d | 2017-01-31 20:36:14 | [diff] [blame] | 211 | |
| 212 | private: |
Andreas Haas | c13cae8 | 2017-11-16 12:54:38 | [diff] [blame^] | 213 | friend class gin::V8BackgroundTaskRunner; |
Francois Doray | 6d3c64969 | 2017-06-16 19:20:25 | [diff] [blame] | 214 | friend class content::BrowserMainLoopTest_CreateThreadsInSingleProcess_Test; |
fdoray | 1028b07d | 2017-01-31 20:36:14 | [diff] [blame] | 215 | |
Jeffrey He | d628419b | 2017-08-23 18:51:51 | [diff] [blame] | 216 | // Returns the maximum number of non-single-threaded non-blocked tasks posted |
| 217 | // with |traits| that can run concurrently in this TaskScheduler. |
fdoray | 1028b07d | 2017-01-31 20:36:14 | [diff] [blame] | 218 | // |
| 219 | // Do not use this method. To process n items, post n tasks that each process |
Jeffrey He | d628419b | 2017-08-23 18:51:51 | [diff] [blame] | 220 | // 1 item rather than GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated() |
| 221 | // tasks that each process |
| 222 | // n/GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated() items. |
fdoray | 1028b07d | 2017-01-31 20:36:14 | [diff] [blame] | 223 | // |
| 224 | // TODO(fdoray): Remove this method. https://crbug.com/687264 |
Jeffrey He | d628419b | 2017-08-23 18:51:51 | [diff] [blame] | 225 | virtual int GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated( |
fdoray | 1028b07d | 2017-01-31 20:36:14 | [diff] [blame] | 226 | const TaskTraits& traits) const = 0; |
fdoray | 67ecfb5 | 2016-05-02 14:49:03 | [diff] [blame] | 227 | }; |
| 228 | |
| 229 | } // namespace base |
| 230 | |
| 231 | #endif // BASE_TASK_SCHEDULER_TASK_SCHEDULER_H_ |