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
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
// 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_TRAITS_H_
#define BASE_TASK_SCHEDULER_TASK_TRAITS_H_
#include <stdint.h>
#include <iosfwd>
#include <type_traits>
#include "base/base_export.h"
#include "base/task_scheduler/task_traits_details.h"
#include "build/build_config.h"
namespace base {
// Valid priorities supported by the task scheduler. Note: internal algorithms
// depend on priorities being expressed as a continuous zero-based list from
// lowest to highest priority. Users of this API shouldn't otherwise care about
// nor use the underlying values.
enum class TaskPriority {
// This will always be equal to the lowest priority available.
LOWEST = 0,
// User won't notice if this task takes an arbitrarily long time to complete.
BACKGROUND = LOWEST,
// This task affects UI or responsiveness of future user interactions. It is
// not an immediate response to a user interaction.
// Examples:
// - Updating the UI to reflect progress on a long task.
// - Loading data that might be shown in the UI after a future user
// interaction.
USER_VISIBLE,
// This task affects UI immediately after a user interaction.
// Example: Generating data shown in the UI immediately after a click.
USER_BLOCKING,
// This will always be equal to the highest priority available.
HIGHEST = USER_BLOCKING,
};
// Valid shutdown behaviors supported by the task scheduler.
enum class TaskShutdownBehavior {
// Tasks posted with this mode which have not started executing before
// shutdown is initiated will never run. Tasks with this mode running at
// shutdown will be ignored (the worker will not be joined).
//
// This option provides a nice way to post stuff you don't want blocking
// shutdown. For example, you might be doing a slow DNS lookup and if it's
// blocked on the OS, you may not want to stop shutdown, since the result
// doesn't really matter at that point.
//
// However, you need to be very careful what you do in your callback when you
// use this option. Since the thread will continue to run until the OS
// terminates the process, the app can be in the process of tearing down when
// you're running. This means any singletons or global objects you use may
// suddenly become invalid out from under you. For this reason, it's best to
// use this only for slow but simple operations like the DNS example.
CONTINUE_ON_SHUTDOWN,
// Tasks posted with this mode that have not started executing at
// shutdown will never run. However, any task that has already begun
// executing when shutdown is invoked will be allowed to continue and
// will block shutdown until completion.
//
// Note: Because TaskScheduler::Shutdown() may block while these tasks are
// executing, care must be taken to ensure that they do not block on the
// thread that called TaskScheduler::Shutdown(), as this may lead to deadlock.
SKIP_ON_SHUTDOWN,
// Tasks posted with this mode before shutdown is complete will block shutdown
// until they're executed. Generally, this should be used only to save
// critical user data.
//
// Note: Tasks with BACKGROUND priority that block shutdown will be promoted
// to USER_VISIBLE priority during shutdown.
BLOCK_SHUTDOWN,
};
// Tasks with this trait may block. This includes but is not limited to tasks
// that wait on synchronous file I/O operations: read or write a file from disk,
// interact with a pipe or a socket, rename or delete a file, enumerate files in
// a directory, etc. This trait isn't required for the mere use of locks. For
// tasks that block on base/ synchronization primitives, see the
// WithBaseSyncPrimitives trait.
struct MayBlock {};
// Tasks with this trait will pass base::AssertWaitAllowed(), i.e. will be
// allowed on the following methods :
// - base::WaitableEvent::Wait
// - base::ConditionVariable::Wait
// - base::PlatformThread::Join
// - base::PlatformThread::Sleep
// - base::Process::WaitForExit
// - base::Process::WaitForExitWithTimeout
//
// Tasks should generally not use these methods.
//
// Instead of waiting on a WaitableEvent or a ConditionVariable, put the work
// that should happen after the wait in a callback and post that callback from
// where the WaitableEvent or ConditionVariable would have been signaled. If
// something needs to be scheduled after many tasks have executed, use
// base::BarrierClosure.
//
// On Windows, join processes asynchronously using base::win::ObjectWatcher.
//
// MayBlock() must be specified in conjunction with this trait if and only if
// removing usage of methods listed above in the labeled tasks would still
// result in tasks that may block (per MayBlock()'s definition).
//
// In doubt, consult with //base/task_scheduler/OWNERS.
struct WithBaseSyncPrimitives {};
// Describes immutable metadata for a single task or a group of tasks.
class BASE_EXPORT TaskTraits {
private:
// ValidTrait ensures TaskTraits' constructor only accepts appropriate types.
struct ValidTrait {
ValidTrait(TaskPriority) {}
ValidTrait(TaskShutdownBehavior) {}
ValidTrait(MayBlock) {}
ValidTrait(WithBaseSyncPrimitives) {}
};
public:
// Invoking this constructor without arguments produces TaskTraits that are
// appropriate for tasks that
// (1) don't block (ref. MayBlock() and WithBaseSyncPrimitives()),
// (2) prefer inheriting the current priority to specifying their own, and
// (3) can either block shutdown or be skipped on shutdown
// (TaskScheduler implementation is free to choose a fitting default).
//
// To get TaskTraits for tasks that require stricter guarantees and/or know
// the specific TaskPriority appropriate for them, provide arguments of type
// TaskPriority, TaskShutdownBehavior, MayBlock, and/or WithBaseSyncPrimitives
// in any order to the constructor.
//
// E.g.
// constexpr base::TaskTraits default_traits = {};
// constexpr base::TaskTraits user_visible_traits =
// {base::TaskPriority::USER_VISIBLE};
// constexpr base::TaskTraits user_visible_may_block_traits = {
// base::TaskPriority::USER_VISIBLE, base::MayBlock()};
// constexpr base::TaskTraits other_user_visible_may_block_traits = {
// base::MayBlock(), base::TaskPriority::USER_VISIBLE};
template <class... ArgTypes,
class CheckArgumentsAreValid = internal::InitTypes<
decltype(ValidTrait(std::declval<ArgTypes>()))...>>
constexpr TaskTraits(ArgTypes... args)
: priority_set_explicitly_(
internal::HasArgOfType<TaskPriority, ArgTypes...>::value),
priority_(internal::GetValueFromArgList(
internal::EnumArgGetter<TaskPriority, TaskPriority::USER_VISIBLE>(),
args...)),
shutdown_behavior_set_explicitly_(
internal::HasArgOfType<TaskShutdownBehavior, ArgTypes...>::value),
shutdown_behavior_(internal::GetValueFromArgList(
internal::EnumArgGetter<TaskShutdownBehavior,
TaskShutdownBehavior::SKIP_ON_SHUTDOWN>(),
args...)),
may_block_(internal::GetValueFromArgList(
internal::BooleanArgGetter<MayBlock>(),
args...)),
with_base_sync_primitives_(internal::GetValueFromArgList(
internal::BooleanArgGetter<WithBaseSyncPrimitives>(),
args...)) {}
constexpr TaskTraits(const TaskTraits& other) = default;
TaskTraits& operator=(const TaskTraits& other) = default;
// Returns TaskTraits constructed by combining |left| and |right|. If a trait
// is specified in both |left| and |right|, the returned TaskTraits will have
// the value from |right|.
static constexpr TaskTraits Override(const TaskTraits& left,
const TaskTraits& right) {
return TaskTraits(left, right);
}
// Returns true if the priority was set explicitly.
constexpr bool priority_set_explicitly() const {
return priority_set_explicitly_;
}
// Returns the priority of tasks with these traits.
constexpr TaskPriority priority() const { return priority_; }
// Returns true if the shutdown behavior was set explicitly.
constexpr bool shutdown_behavior_set_explicitly() const {
return shutdown_behavior_set_explicitly_;
}
// Returns the shutdown behavior of tasks with these traits.
constexpr TaskShutdownBehavior shutdown_behavior() const {
return shutdown_behavior_;
}
// Returns true if tasks with these traits may block.
constexpr bool may_block() const { return may_block_; }
// Returns true if tasks with these traits may use base/ sync primitives.
constexpr bool with_base_sync_primitives() const {
return with_base_sync_primitives_;
}
private:
constexpr TaskTraits(const TaskTraits& left, const TaskTraits& right)
: priority_set_explicitly_(left.priority_set_explicitly_ ||
right.priority_set_explicitly_),
priority_(right.priority_set_explicitly_ ? right.priority_
: left.priority_),
shutdown_behavior_set_explicitly_(
left.shutdown_behavior_set_explicitly_ ||
right.shutdown_behavior_set_explicitly_),
shutdown_behavior_(right.shutdown_behavior_set_explicitly_
? right.shutdown_behavior_
: left.shutdown_behavior_),
may_block_(left.may_block_ || right.may_block_),
with_base_sync_primitives_(left.with_base_sync_primitives_ ||
right.with_base_sync_primitives_) {}
bool priority_set_explicitly_;
TaskPriority priority_;
bool shutdown_behavior_set_explicitly_;
TaskShutdownBehavior shutdown_behavior_;
bool may_block_;
bool with_base_sync_primitives_;
};
// Returns string literals for the enums defined in this file. These methods
// should only be used for tracing and debugging.
BASE_EXPORT const char* TaskPriorityToString(TaskPriority task_priority);
BASE_EXPORT const char* TaskShutdownBehaviorToString(
TaskShutdownBehavior task_priority);
// Stream operators so that the enums defined in this file can be used in
// DCHECK and EXPECT statements.
BASE_EXPORT std::ostream& operator<<(std::ostream& os,
const TaskPriority& shutdown_behavior);
BASE_EXPORT std::ostream& operator<<(
std::ostream& os,
const TaskShutdownBehavior& shutdown_behavior);
} // namespace base
#endif // BASE_TASK_SCHEDULER_TASK_TRAITS_H_
|