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 3 // found in the LICENSE file. 4 5 #ifndef BASE_TASK_SCHEDULER_TASK_TRAITS_H_ 6 #define BASE_TASK_SCHEDULER_TASK_TRAITS_H_ 7 8 #include <stdint.h> 9 10 #include <iosfwd> 11 12 #include "base/base_export.h" 13 #include "build/build_config.h" 14 15 namespace base { 16 17 // Valid priorities supported by the task scheduler. Note: internal algorithms 18 // 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 // nor use the underlying values. 21 enum class TaskPriority { 22 // This will always be equal to the lowest priority available. 23 LOWEST = 0, 24 // User won't notice if this task takes an arbitrarily long time to complete. 25 BACKGROUND = LOWEST, 26 // This task affects UI or responsiveness of future user interactions. It is 27 // not an immediate response to a user interaction. 28 // Examples: 29 // - Updating the UI to reflect progress on a long task. 30 // - Loading data that might be shown in the UI after a future user 31 // interaction. 32 USER_VISIBLE, 33 // This task affects UI immediately after a user interaction. 34 // Example: Generating data shown in the UI immediately after a click. 35 USER_BLOCKING, 36 // This will always be equal to the highest priority available. 37 HIGHEST = USER_BLOCKING, 38 }; 39 40 // Valid shutdown behaviors supported by the task scheduler. 41 enum class TaskShutdownBehavior { 42 // Tasks posted with this mode which have not started executing before 43 // shutdown is initiated will never run. Tasks with this mode running at 44 // shutdown will be ignored (the worker will not be joined). 45 // 46 // This option provides a nice way to post stuff you don't want blocking 47 // shutdown. For example, you might be doing a slow DNS lookup and if it's 48 // blocked on the OS, you may not want to stop shutdown, since the result 49 // doesn't really matter at that point. 50 // 51 // However, you need to be very careful what you do in your callback when you 52 // use this option. Since the thread will continue to run until the OS 53 // terminates the process, the app can be in the process of tearing down when 54 // you're running. This means any singletons or global objects you use may 55 // suddenly become invalid out from under you. For this reason, it's best to 56 // use this only for slow but simple operations like the DNS example. 57 CONTINUE_ON_SHUTDOWN, 58 59 // Tasks posted with this mode that have not started executing at 60 // shutdown will never run. However, any task that has already begun 61 // executing when shutdown is invoked will be allowed to continue and 62 // will block shutdown until completion. 63 // 64 // Note: Because TaskScheduler::Shutdown() may block while these tasks are 65 // executing, care must be taken to ensure that they do not block on the 66 // thread that called TaskScheduler::Shutdown(), as this may lead to deadlock. 67 SKIP_ON_SHUTDOWN, 68 69 // Tasks posted with this mode before shutdown is complete will block shutdown 70 // until they're executed. Generally, this should be used only to save 71 // critical user data. 72 // 73 // Note: Tasks with BACKGROUND priority that block shutdown will be promoted 74 // to USER_VISIBLE priority during shutdown. 75 BLOCK_SHUTDOWN, 76 }; 77 78 // Describes metadata for a single task or a group of tasks. 79 class BASE_EXPORT TaskTraits { 80 public: 81 // Constructs a default TaskTraits for tasks that 82 // (1) don't block (ref. MayBlock() and WithBaseSyncPrimitives()), 83 // (2) prefer inheriting the current priority to specifying their own, and 84 // (3) can either block shutdown or be skipped on shutdown 85 // (TaskScheduler implementation is free to choose a fitting default). 86 // Tasks that require stricter guarantees and/or know the specific 87 // TaskPriority appropriate for them should highlight those by requesting 88 // explicit traits below. 89 TaskTraits(); 90 TaskTraits(const TaskTraits& other) = default; 91 TaskTraits& operator=(const TaskTraits& other) = default; 92 ~TaskTraits(); 93 94 // Tasks with this trait may block. This includes but is not limited to tasks 95 // that wait on synchronous file I/O operations: read or write a file from 96 // disk, interact with a pipe or a socket, rename or delete a file, enumerate 97 // files in a directory, etc. This trait isn't required for the mere use of 98 // locks. For tasks that block on base/ synchronization primitives, see 99 // WithBaseSyncPrimitives(). 100 TaskTraits& MayBlock(); 101 102 // Tasks with this trait will pass base::AssertWaitAllowed(), i.e. will be 103 // allowed on the following methods : 104 // - base::WaitableEvent::Wait 105 // - base::ConditionVariable::Wait 106 // - base::PlatformThread::Join 107 // - base::PlatformThread::Sleep 108 // - base::Process::WaitForExit 109 // - base::Process::WaitForExitWithTimeout 110 // 111 // Tasks should generally not use these methods. 112 // 113 // Instead of waiting on a WaitableEvent or a ConditionVariable, put the work 114 // that should happen after the wait in a callback and post that callback from 115 // where the WaitableEvent or ConditionVariable would have been signaled. If 116 // something needs to be scheduled after many tasks have executed, use 117 // base::BarrierClosure. 118 // 119 // Avoid creating threads. Instead, use 120 // base::Create(Sequenced|SingleTreaded)TaskRunnerWithTraits(). If a thread is 121 // really needed, make it non-joinable and add cleanup work at the end of the 122 // thread's main function (if using base::Thread, override Cleanup()). 123 // 124 // On Windows, join processes asynchronously using base::win::ObjectWatcher. 125 // 126 // MayBlock() must be specified in conjunction with this trait if and only if 127 // removing usage of methods listed above in the labeled tasks would still 128 // result in tasks that may block (per MayBlock()'s definition). 129 // 130 // In doubt, consult with //base/task_scheduler/OWNERS. 131 TaskTraits& WithBaseSyncPrimitives(); 132 133 // Applies |priority| to tasks with these traits. 134 TaskTraits& WithPriority(TaskPriority priority); 135 136 // Applies |shutdown_behavior| to tasks with these traits. 137 TaskTraits& WithShutdownBehavior(TaskShutdownBehavior shutdown_behavior); 138 139 // Returns true if tasks with these traits may block. 140 bool may_block() const { return may_block_; } 141 142 // Returns true if tasks with these traits may use base/ sync primitives. 143 bool with_base_sync_primitives() const { return with_base_sync_primitives_; } 144 145 // Returns the priority of tasks with these traits. 146 TaskPriority priority() const { return priority_; } 147 148 // Returns the shutdown behavior of tasks with these traits. 149 TaskShutdownBehavior shutdown_behavior() const { return shutdown_behavior_; } 150 151 private: 152 bool may_block_; 153 bool with_base_sync_primitives_; 154 TaskPriority priority_; 155 TaskShutdownBehavior shutdown_behavior_; 156 }; 157 158 // Returns string literals for the enums defined in this file. These methods 159 // should only be used for tracing and debugging. 160 BASE_EXPORT const char* TaskPriorityToString(TaskPriority task_priority); 161 BASE_EXPORT const char* TaskShutdownBehaviorToString( 162 TaskShutdownBehavior task_priority); 163 164 // Stream operators so that the enums defined in this file can be used in 165 // DCHECK and EXPECT statements. 166 BASE_EXPORT std::ostream& operator<<(std::ostream& os, 167 const TaskPriority& shutdown_behavior); 168 BASE_EXPORT std::ostream& operator<<( 169 std::ostream& os, 170 const TaskShutdownBehavior& shutdown_behavior); 171 172 } // namespace base 173 174 #endif // BASE_TASK_SCHEDULER_TASK_TRAITS_H_ 175