Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: base/task_scheduler/task_traits.h

Issue 2829083002: Add constexpr TaskTraits constructor. (Closed)
Patch Set: fix unused warning Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/BUILD.gn ('k') | base/task_scheduler/task_traits.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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_
OLDNEW
« no previous file with comments | « base/BUILD.gn ('k') | base/task_scheduler/task_traits.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698