Home | History | Annotate | Download | only in task_scheduler
      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