summaryrefslogtreecommitdiff
path: root/chromium/base/task_scheduler/task_scheduler.h
blob: 2e436ce8f2c8f2d2c71b41264964ec5e9a3ca5f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_TASK_SCHEDULER_TASK_SCHEDULER_H_
#define BASE_TASK_SCHEDULER_TASK_SCHEDULER_H_

#include <memory>
#include <vector>

#include "base/base_export.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_piece.h"
#include "base/task_runner.h"
#include "base/task_scheduler/scheduler_worker_pool_params.h"
#include "base/task_scheduler/single_thread_task_runner_thread_mode.h"
#include "base/task_scheduler/task_traits.h"
#include "base/time/time.h"
#include "build/build_config.h"

namespace gin {
class V8Platform;
}

namespace tracked_objects {
class Location;
}

namespace base {

class HistogramBase;

// Interface for a task scheduler and static methods to manage the instance used
// by the post_task.h API.
//
// The task scheduler doesn't create threads until Start() is called. Tasks can
// be posted at any time but will not run until after Start() is called.
//
// The instance methods of this class are thread-safe.
//
// Note: All base/task_scheduler users should go through post_task.h instead of
// TaskScheduler except for the one callsite per process which manages the
// process's instance.
class BASE_EXPORT TaskScheduler {
 public:
  struct BASE_EXPORT InitParams {
    InitParams(
        const SchedulerWorkerPoolParams& background_worker_pool_params_in,
        const SchedulerWorkerPoolParams&
            background_blocking_worker_pool_params_in,
        const SchedulerWorkerPoolParams& foreground_worker_pool_params_in,
        const SchedulerWorkerPoolParams&
            foreground_blocking_worker_pool_params_in);
    ~InitParams();

    const SchedulerWorkerPoolParams background_worker_pool_params;
    const SchedulerWorkerPoolParams background_blocking_worker_pool_params;
    const SchedulerWorkerPoolParams foreground_worker_pool_params;
    const SchedulerWorkerPoolParams foreground_blocking_worker_pool_params;
  };

  // Destroying a TaskScheduler is not allowed in production; it is always
  // leaked. In tests, it should only be destroyed after JoinForTesting() has
  // returned.
  virtual ~TaskScheduler() = default;

  // Allows the task scheduler to create threads and run tasks following the
  // |init_params| specification. CHECKs on failure.
  virtual void Start(const InitParams& init_params) = 0;

  // Posts |task| with a |delay| and specific |traits|. |delay| can be zero.
  // For one off tasks that don't require a TaskRunner.
  virtual void PostDelayedTaskWithTraits(
      const tracked_objects::Location& from_here,
      const TaskTraits& traits,
      OnceClosure task,
      TimeDelta delay) = 0;

  // Returns a TaskRunner whose PostTask invocations result in scheduling tasks
  // using |traits|. Tasks may run in any order and in parallel.
  virtual scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits(
      const TaskTraits& traits) = 0;

  // Returns a SequencedTaskRunner whose PostTask invocations result in
  // scheduling tasks using |traits|. Tasks run one at a time in posting order.
  virtual scoped_refptr<SequencedTaskRunner>
  CreateSequencedTaskRunnerWithTraits(const TaskTraits& traits) = 0;

  // Returns a SingleThreadTaskRunner whose PostTask invocations result in
  // scheduling tasks using |traits|. Tasks run on a single thread in posting
  // order.
  virtual scoped_refptr<SingleThreadTaskRunner>
  CreateSingleThreadTaskRunnerWithTraits(
      const TaskTraits& traits,
      SingleThreadTaskRunnerThreadMode thread_mode) = 0;

#if defined(OS_WIN)
  // Returns a SingleThreadTaskRunner whose PostTask invocations result in
  // scheduling tasks using |traits| in a COM Single-Threaded Apartment. Tasks
  // run in the same Single-Threaded Apartment in posting order for the returned
  // SingleThreadTaskRunner. There is not necessarily a one-to-one
  // correspondence between SingleThreadTaskRunners and Single-Threaded
  // Apartments. The implementation is free to share apartments or create new
  // apartments as necessary. In either case, care should be taken to make sure
  // COM pointers are not smuggled across apartments.
  virtual scoped_refptr<SingleThreadTaskRunner>
  CreateCOMSTATaskRunnerWithTraits(
      const TaskTraits& traits,
      SingleThreadTaskRunnerThreadMode thread_mode) = 0;
#endif  // defined(OS_WIN)

  // Returns a vector of all histograms available in this task scheduler.
  virtual std::vector<const HistogramBase*> GetHistograms() const = 0;

  // Synchronously shuts down the scheduler. Once this is called, only tasks
  // posted with the BLOCK_SHUTDOWN behavior will be run. When this returns:
  // - All SKIP_ON_SHUTDOWN tasks that were already running have completed their
  //   execution.
  // - All posted BLOCK_SHUTDOWN tasks have completed their execution.
  // - CONTINUE_ON_SHUTDOWN tasks might still be running.
  // Note that an implementation can keep threads and other resources alive to
  // support running CONTINUE_ON_SHUTDOWN after this returns. This can only be
  // called once.
  virtual void Shutdown() = 0;

  // Waits until there are no pending undelayed tasks. May be called in tests
  // to validate that a condition is met after all undelayed tasks have run.
  //
  // Does not wait for delayed tasks. Waits for undelayed tasks posted from
  // other threads during the call. Returns immediately when shutdown completes.
  virtual void FlushForTesting() = 0;

  // Joins all threads. Tasks that are already running are allowed to complete
  // their execution. This can only be called once. Using this task scheduler
  // instance to create task runners or post tasks is not permitted during or
  // after this call.
  virtual void JoinForTesting() = 0;

// CreateAndStartWithDefaultParams(), Create(), and SetInstance() register a
// TaskScheduler to handle tasks posted through the post_task.h API for this
// process.
//
// Processes that need to initialize TaskScheduler with custom params or that
// need to allow tasks to be posted before the TaskScheduler creates its
// threads should use Create() followed by Start(). Other processes can use
// CreateAndStartWithDefaultParams().
//
// A registered TaskScheduler is only deleted when a new TaskScheduler is
// registered. The last registered TaskScheduler is leaked on shutdown. The
// methods below must not be called when TaskRunners created by a previous
// TaskScheduler are still alive. The methods are not thread-safe; proper
// synchronization is required to use the post_task.h API after registering a
// new TaskScheduler.

#if !defined(OS_NACL)
  // Creates and starts a task scheduler using default params. |name| is used to
  // label threads and histograms. It should identify the component that calls
  // this. Start() is called by this method; it is invalid to call it again
  // afterwards. CHECKs on failure. For tests, prefer
  // base::test::ScopedTaskEnvironment (ensures isolation).
  static void CreateAndStartWithDefaultParams(StringPiece name);
#endif  // !defined(OS_NACL)

  // Creates a ready to start task scheduler. |name| is used to label threads
  // and histograms. It should identify the component that creates the
  // TaskScheduler. The task scheduler doesn't create threads until Start() is
  // called. Tasks can be posted at any time but will not run until after
  // Start() is called. For tests, prefer base::test::ScopedTaskEnvironment
  // (ensures isolation).
  static void Create(StringPiece name);

  // Registers |task_scheduler| to handle tasks posted through the post_task.h
  // API for this process. For tests, prefer base::test::ScopedTaskScheduler
  // (ensures isolation).
  static void SetInstance(std::unique_ptr<TaskScheduler> task_scheduler);

  // Retrieve the TaskScheduler set via SetInstance() or
  // CreateAndSet(Simple|Default)TaskScheduler(). This should be used very
  // rarely; most users of TaskScheduler should use the post_task.h API. In
  // particular, refrain from doing
  //   if (!TaskScheduler::GetInstance()) {
  //     TaskScheduler::SetInstance(...);
  //     base::PostTask(...);
  //   }
  // instead make sure to SetInstance() early in one determinstic place in the
  // process' initialization phase.
  // In doubt, consult with //base/task_scheduler/OWNERS.
  static TaskScheduler* GetInstance();

 private:
  friend class gin::V8Platform;

  // Returns the maximum number of non-single-threaded tasks posted with
  // |traits| that can run concurrently in this TaskScheduler.
  //
  // Do not use this method. To process n items, post n tasks that each process
  // 1 item rather than GetMaxConcurrentTasksWithTraitsDeprecated() tasks that
  // each process n/GetMaxConcurrentTasksWithTraitsDeprecated() items.
  //
  // TODO(fdoray): Remove this method. https://crbug.com/687264
  virtual int GetMaxConcurrentTasksWithTraitsDeprecated(
      const TaskTraits& traits) const = 0;
};

}  // namespace base

#endif  // BASE_TASK_SCHEDULER_TASK_SCHEDULER_H_