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