OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_TASK_SCHEDULER_TASK_TRAITS_H_ | 5 #ifndef BASE_TASK_SCHEDULER_TASK_TRAITS_H_ |
6 #define BASE_TASK_SCHEDULER_TASK_TRAITS_H_ | 6 #define BASE_TASK_SCHEDULER_TASK_TRAITS_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <iosfwd> | 10 #include <iosfwd> |
11 #include <type_traits> | |
12 #include <utility> | |
11 | 13 |
12 #include "base/base_export.h" | 14 #include "base/base_export.h" |
13 #include "build/build_config.h" | 15 #include "build/build_config.h" |
14 | 16 |
15 namespace base { | 17 namespace base { |
16 | 18 |
17 // Valid priorities supported by the task scheduler. Note: internal algorithms | 19 // Valid priorities supported by the task scheduler. Note: internal algorithms |
18 // depend on priorities being expressed as a continuous zero-based list from | 20 // depend on priorities being expressed as a continuous zero-based list from |
19 // lowest to highest priority. Users of this API shouldn't otherwise care about | 21 // lowest to highest priority. Users of this API shouldn't otherwise care about |
20 // nor use the underlying values. | 22 // nor use the underlying values. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 | 72 |
71 // Tasks posted with this mode before shutdown is complete will block shutdown | 73 // Tasks posted with this mode before shutdown is complete will block shutdown |
72 // until they're executed. Generally, this should be used only to save | 74 // until they're executed. Generally, this should be used only to save |
73 // critical user data. | 75 // critical user data. |
74 // | 76 // |
75 // Note: Tasks with BACKGROUND priority that block shutdown will be promoted | 77 // Note: Tasks with BACKGROUND priority that block shutdown will be promoted |
76 // to USER_VISIBLE priority during shutdown. | 78 // to USER_VISIBLE priority during shutdown. |
77 BLOCK_SHUTDOWN, | 79 BLOCK_SHUTDOWN, |
78 }; | 80 }; |
79 | 81 |
82 // Tasks with this trait may block. This includes but is not limited to tasks | |
83 // that wait on synchronous file I/O operations: read or write a file from disk, | |
84 // interact with a pipe or a socket, rename or delete a file, enumerate files in | |
85 // a directory, etc. This trait isn't required for the mere use of locks. For | |
86 // tasks that block on base/ synchronization primitives, see | |
87 // WithBaseSyncPrimitives(). | |
robliao
2017/04/21 18:02:06
WithBaseSyncPrimitives() -> the WithBaseSyncPrimit
fdoray
2017/04/21 20:35:20
Done.
| |
88 struct MayBlock {}; | |
89 | |
90 // Tasks with this trait will pass base::AssertWaitAllowed(), i.e. will be | |
91 // allowed on the following methods : | |
92 // - base::WaitableEvent::Wait | |
93 // - base::ConditionVariable::Wait | |
94 // - base::PlatformThread::Join | |
95 // - base::PlatformThread::Sleep | |
96 // - base::Process::WaitForExit | |
97 // - base::Process::WaitForExitWithTimeout | |
98 // | |
99 // Tasks should generally not use these methods. | |
100 // | |
101 // Instead of waiting on a WaitableEvent or a ConditionVariable, put the work | |
102 // that should happen after the wait in a callback and post that callback from | |
103 // where the WaitableEvent or ConditionVariable would have been signaled. If | |
104 // something needs to be scheduled after many tasks have executed, use | |
105 // base::BarrierClosure. | |
106 // | |
107 // Avoid creating threads. Instead, use | |
robliao
2017/04/21 18:02:06
This guidance should probably be placed somewhere
fdoray
2017/04/21 20:35:20
Done. Writing a CL that adds it to base::Thread/ba
fdoray
2017/04/21 20:43:18
https://codereview.chromium.org/2834783004/
| |
108 // base::Create(Sequenced|SingleTreaded)TaskRunnerWithTraits(). If a thread is | |
109 // really needed, make it non-joinable and add cleanup work at the end of the | |
110 // thread's main function (if using base::Thread, override Cleanup()). | |
111 // | |
112 // On Windows, join processes asynchronously using base::win::ObjectWatcher. | |
113 // | |
114 // MayBlock() must be specified in conjunction with this trait if and only if | |
115 // removing usage of methods listed above in the labeled tasks would still | |
116 // result in tasks that may block (per MayBlock()'s definition). | |
117 // | |
118 // In doubt, consult with //base/task_scheduler/OWNERS. | |
119 struct WithBaseSyncPrimitives {}; | |
120 | |
121 namespace internal { | |
robliao
2017/04/21 18:02:06
Place this is task_traits_details.h or task_traits
robliao
2017/04/21 18:03:13
Wow, that didn't come out right at all.
Place this
fdoray
2017/04/21 20:35:19
Done.
| |
122 | |
123 // CheckNoArgOfType() generates a compile-time error if it receives an argument | |
124 // of type UnwantedType. The 2nd overload checks the type of the first argument | |
robliao
2017/04/21 18:02:06
Nit: 2nd -> second and 1st -> first
fdoray
2017/04/21 20:35:19
Done.
| |
125 // and makes a recursive call with the remaining arguments. The 1st overload | |
126 // takes no argument and is used to end the recursion. Both overloads return a | |
127 // bool because it is invalid for a constexpr function to return void. | |
128 template <class UnwantedType> | |
129 constexpr bool CheckNoArgOfType() { | |
130 return true; | |
131 } | |
132 | |
133 template <class UnwantedType, class FirstArgType, class... ArgTypes> | |
134 constexpr bool CheckNoArgOfType(const FirstArgType&, const ArgTypes&... args) { | |
135 static_assert(!std::is_same<UnwantedType, FirstArgType>::value, | |
136 "Multiple arguments of the same type were provided to the " | |
137 "constructor of TaskTraits."); | |
138 return CheckNoArgOfType<UnwantedType>(args...); | |
139 } | |
140 | |
141 // When the following call is made: | |
142 // GetValueFromArgList(CallFirstTag(), GetterType(), args...); | |
143 // The compiler prefers using the 3rd overload of GetValueFromArgList(), because | |
144 // the type of the first argument matches exactly. That overload uses | |
145 // Getter::operator()(FirstArgType) to extract a value from |first_arg|. If | |
146 // Getter::operator()(FirstArgType) isn't defined, the compiler uses the 1st or | |
147 // the 2nd overload instead (depending on whether |args| is empty). The 1st | |
148 // overload returns a default value obtained from Getter::operator()(). The 2nd | |
149 // overload discards |first_arg| and calls back GetValueFromArgList() with | |
150 // CallFirstTag() as first argument. | |
151 struct CallSecondTag {}; | |
152 struct CallFirstTag : CallSecondTag {}; | |
153 | |
154 // Overload 1: Default value. | |
155 template <class GetterType> | |
156 constexpr auto GetValueFromArgList(CallSecondTag, GetterType getter) | |
157 -> decltype(getter()) { | |
158 return getter(); | |
159 } | |
160 | |
161 // Overload 2: Discard first argument. | |
162 template <class GetterType, class FirstArgType, class... ArgTypes> | |
163 constexpr auto GetValueFromArgList(CallSecondTag, | |
164 GetterType getter, | |
165 const FirstArgType&, | |
166 const ArgTypes&... args) | |
167 -> decltype(GetValueFromArgList(CallFirstTag(), getter, args...)) { | |
168 return GetValueFromArgList(CallFirstTag(), getter, args...); | |
169 } | |
170 | |
171 // Overload 3: Get value from first argument. Check that no argument in |args| | |
172 // has the same type as |first_arg|. | |
173 template <class GetterType, | |
174 class FirstArgType, | |
175 class... ArgTypes, | |
176 class Instantiation = decltype( | |
177 std::declval<GetterType>()(std::declval<FirstArgType>()))> | |
178 constexpr typename GetterType::ValueType GetValueFromArgList( | |
179 CallFirstTag, | |
180 GetterType getter, | |
181 const FirstArgType& first_arg, | |
182 const ArgTypes&... args) { | |
183 // CheckNoArgOfType() is invoked as part of a comma operator statement to | |
184 // avoid an unused return value warning. | |
185 return CheckNoArgOfType<FirstArgType>(args...), getter(first_arg); | |
186 } | |
187 | |
188 template <typename ArgType> | |
189 struct BooleanArgGetter { | |
190 using ValueType = bool; | |
191 constexpr ValueType operator()(ArgType) const { return true; } | |
192 constexpr ValueType operator()() const { return false; } | |
193 }; | |
194 | |
195 template <typename ArgType, ArgType DefaultValue> | |
196 struct EnumArgGetter { | |
197 using ValueType = ArgType; | |
198 constexpr ValueType operator()(ArgType arg) const { return arg; } | |
199 constexpr ValueType operator()() const { return DefaultValue; } | |
200 }; | |
201 | |
202 } // namespace internal | |
203 | |
80 // Describes metadata for a single task or a group of tasks. | 204 // Describes metadata for a single task or a group of tasks. |
81 class BASE_EXPORT TaskTraits { | 205 class BASE_EXPORT TaskTraits { |
82 public: | 206 public: |
83 // Constructs a default TaskTraits for tasks that | 207 // Invoking this constructor without arguments produces TaskTraits that are |
208 // appropriate for tasks that | |
84 // (1) don't block (ref. MayBlock() and WithBaseSyncPrimitives()), | 209 // (1) don't block (ref. MayBlock() and WithBaseSyncPrimitives()), |
85 // (2) prefer inheriting the current priority to specifying their own, and | 210 // (2) prefer inheriting the current priority to specifying their own, and |
86 // (3) can either block shutdown or be skipped on shutdown | 211 // (3) can either block shutdown or be skipped on shutdown |
87 // (TaskScheduler implementation is free to choose a fitting default). | 212 // (TaskScheduler implementation is free to choose a fitting default). |
88 // Tasks that require stricter guarantees and/or know the specific | 213 // |
89 // TaskPriority appropriate for them should highlight those by requesting | 214 // To get TaskTraits for tasks that require stricter guarantees and/or know |
90 // explicit traits below. | 215 // the specific TaskPriority appropriate for them, provide arguments of type |
91 TaskTraits(); | 216 // TaskPriority, TaskShutdownBehavior, MayBlock and/or WithBaseSyncPrimitives |
92 TaskTraits(const TaskTraits& other) = default; | 217 // in any order to the constructor. |
218 // | |
219 // E.g. | |
220 // constexpr TaskTraits default_traits; | |
221 // constexpr TaskTraits user_visible_traits = {TaskPriority::USER_VISIBLE}; | |
222 // constexpr TaskTraits user_visible_may_block_traits = { | |
223 // TaskPriority::USER_VISIBLE, MayBlock()}; | |
224 // constexpr TaskTraits other_user_visible_may_block_traits = { | |
225 // MayBlock(), TaskPriority::USER_VISIBLE}; | |
226 template <class... ArgTypes> | |
227 constexpr TaskTraits(const ArgTypes&... args) | |
228 : priority_(internal::GetValueFromArgList( | |
229 internal::CallFirstTag(), | |
230 internal::EnumArgGetter<base::TaskPriority, | |
231 base::TaskPriority::INHERITED>(), | |
232 args...)), | |
233 shutdown_behavior_(internal::GetValueFromArgList( | |
234 internal::CallFirstTag(), | |
235 internal::EnumArgGetter< | |
236 base::TaskShutdownBehavior, | |
237 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN>(), | |
238 args...)), | |
239 may_block_(internal::GetValueFromArgList( | |
240 internal::CallFirstTag(), | |
241 internal::BooleanArgGetter<base::MayBlock>(), | |
242 args...)), | |
243 with_base_sync_primitives_(internal::GetValueFromArgList( | |
244 internal::CallFirstTag(), | |
245 internal::BooleanArgGetter<base::WithBaseSyncPrimitives>(), | |
246 args...)) {} | |
247 | |
248 constexpr TaskTraits(const TaskTraits& other) = default; | |
93 TaskTraits& operator=(const TaskTraits& other) = default; | 249 TaskTraits& operator=(const TaskTraits& other) = default; |
94 ~TaskTraits(); | |
95 | 250 |
96 // Tasks with this trait may block. This includes but is not limited to tasks | 251 // Deprecated. |
97 // that wait on synchronous file I/O operations: read or write a file from | 252 TaskTraits& WithPriority(TaskPriority priority); |
98 // disk, interact with a pipe or a socket, rename or delete a file, enumerate | 253 TaskTraits& WithShutdownBehavior(TaskShutdownBehavior shutdown_behavior); |
99 // files in a directory, etc. This trait isn't required for the mere use of | |
100 // locks. For tasks that block on base/ synchronization primitives, see | |
101 // WithBaseSyncPrimitives(). | |
102 TaskTraits& MayBlock(); | 254 TaskTraits& MayBlock(); |
103 | |
104 // Tasks with this trait will pass base::AssertWaitAllowed(), i.e. will be | |
105 // allowed on the following methods : | |
106 // - base::WaitableEvent::Wait | |
107 // - base::ConditionVariable::Wait | |
108 // - base::PlatformThread::Join | |
109 // - base::PlatformThread::Sleep | |
110 // - base::Process::WaitForExit | |
111 // - base::Process::WaitForExitWithTimeout | |
112 // | |
113 // Tasks should generally not use these methods. | |
114 // | |
115 // Instead of waiting on a WaitableEvent or a ConditionVariable, put the work | |
116 // that should happen after the wait in a callback and post that callback from | |
117 // where the WaitableEvent or ConditionVariable would have been signaled. If | |
118 // something needs to be scheduled after many tasks have executed, use | |
119 // base::BarrierClosure. | |
120 // | |
121 // Avoid creating threads. Instead, use | |
122 // base::Create(Sequenced|SingleTreaded)TaskRunnerWithTraits(). If a thread is | |
123 // really needed, make it non-joinable and add cleanup work at the end of the | |
124 // thread's main function (if using base::Thread, override Cleanup()). | |
125 // | |
126 // On Windows, join processes asynchronously using base::win::ObjectWatcher. | |
127 // | |
128 // MayBlock() must be specified in conjunction with this trait if and only if | |
129 // removing usage of methods listed above in the labeled tasks would still | |
130 // result in tasks that may block (per MayBlock()'s definition). | |
131 // | |
132 // In doubt, consult with //base/task_scheduler/OWNERS. | |
133 TaskTraits& WithBaseSyncPrimitives(); | 255 TaskTraits& WithBaseSyncPrimitives(); |
134 | 256 |
135 // Applies |priority| to tasks with these traits. | |
136 TaskTraits& WithPriority(TaskPriority priority); | |
137 | |
138 // Applies |shutdown_behavior| to tasks with these traits. | |
139 TaskTraits& WithShutdownBehavior(TaskShutdownBehavior shutdown_behavior); | |
140 | |
141 // Returns true if tasks with these traits may block. | |
142 bool may_block() const { return may_block_; } | |
143 | |
144 // Returns true if tasks with these traits may use base/ sync primitives. | |
145 bool with_base_sync_primitives() const { return with_base_sync_primitives_; } | |
146 | |
147 // Returns the priority of tasks with these traits. | 257 // Returns the priority of tasks with these traits. |
148 TaskPriority priority() const { return priority_; } | 258 TaskPriority priority() const { return priority_; } |
149 | 259 |
150 // Returns the shutdown behavior of tasks with these traits. | 260 // Returns the shutdown behavior of tasks with these traits. |
151 TaskShutdownBehavior shutdown_behavior() const { return shutdown_behavior_; } | 261 TaskShutdownBehavior shutdown_behavior() const { return shutdown_behavior_; } |
152 | 262 |
263 // Returns true if tasks with these traits may block. | |
264 bool may_block() const { return may_block_; } | |
265 | |
266 // Returns true if tasks with these traits may use base/ sync primitives. | |
267 bool with_base_sync_primitives() const { return with_base_sync_primitives_; } | |
268 | |
153 private: | 269 private: |
270 TaskPriority priority_; | |
271 TaskShutdownBehavior shutdown_behavior_; | |
154 bool may_block_; | 272 bool may_block_; |
155 bool with_base_sync_primitives_; | 273 bool with_base_sync_primitives_; |
156 TaskPriority priority_; | |
157 TaskShutdownBehavior shutdown_behavior_; | |
158 }; | 274 }; |
159 | 275 |
160 // Returns string literals for the enums defined in this file. These methods | 276 // Returns string literals for the enums defined in this file. These methods |
161 // should only be used for tracing and debugging. | 277 // should only be used for tracing and debugging. |
162 BASE_EXPORT const char* TaskPriorityToString(TaskPriority task_priority); | 278 BASE_EXPORT const char* TaskPriorityToString(TaskPriority task_priority); |
163 BASE_EXPORT const char* TaskShutdownBehaviorToString( | 279 BASE_EXPORT const char* TaskShutdownBehaviorToString( |
164 TaskShutdownBehavior task_priority); | 280 TaskShutdownBehavior task_priority); |
165 | 281 |
166 // Stream operators so that the enums defined in this file can be used in | 282 // Stream operators so that the enums defined in this file can be used in |
167 // DCHECK and EXPECT statements. | 283 // DCHECK and EXPECT statements. |
168 BASE_EXPORT std::ostream& operator<<(std::ostream& os, | 284 BASE_EXPORT std::ostream& operator<<(std::ostream& os, |
169 const TaskPriority& shutdown_behavior); | 285 const TaskPriority& shutdown_behavior); |
170 BASE_EXPORT std::ostream& operator<<( | 286 BASE_EXPORT std::ostream& operator<<( |
171 std::ostream& os, | 287 std::ostream& os, |
172 const TaskShutdownBehavior& shutdown_behavior); | 288 const TaskShutdownBehavior& shutdown_behavior); |
173 | 289 |
174 } // namespace base | 290 } // namespace base |
175 | 291 |
176 #endif // BASE_TASK_SCHEDULER_TASK_TRAITS_H_ | 292 #endif // BASE_TASK_SCHEDULER_TASK_TRAITS_H_ |
OLD | NEW |