// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_TASK_SCHEDULER_TASK_TRAITS_H_
#define BASE_TASK_SCHEDULER_TASK_TRAITS_H_

#include <stdint.h>

#include <iosfwd>
#include <type_traits>

#include "base/base_export.h"
#include "base/task_scheduler/task_traits_details.h"
#include "build_config.h"

namespace base {

// Valid priorities supported by the task scheduler. Note: internal algorithms
// depend on priorities being expressed as a continuous zero-based list from
// lowest to highest priority. Users of this API shouldn't otherwise care about
// nor use the underlying values.
enum class TaskPriority {
  // This will always be equal to the lowest priority available.
  LOWEST = 0,
  // User won't notice if this task takes an arbitrarily long time to complete.
  BACKGROUND = LOWEST,
  // This task affects UI or responsiveness of future user interactions. It is
  // not an immediate response to a user interaction.
  // Examples:
  // - Updating the UI to reflect progress on a long task.
  // - Loading data that might be shown in the UI after a future user
  //   interaction.
  USER_VISIBLE,
  // This task affects UI immediately after a user interaction.
  // Example: Generating data shown in the UI immediately after a click.
  USER_BLOCKING,
  // This will always be equal to the highest priority available.
  HIGHEST = USER_BLOCKING,
};

// Valid shutdown behaviors supported by the task scheduler.
enum class TaskShutdownBehavior {
  // Tasks posted with this mode which have not started executing before
  // shutdown is initiated will never run. Tasks with this mode running at
  // shutdown will be ignored (the worker will not be joined).
  //
  // This option provides a nice way to post stuff you don't want blocking
  // shutdown. For example, you might be doing a slow DNS lookup and if it's
  // blocked on the OS, you may not want to stop shutdown, since the result
  // doesn't really matter at that point.
  //
  // However, you need to be very careful what you do in your callback when you
  // use this option. Since the thread will continue to run until the OS
  // terminates the process, the app can be in the process of tearing down when
  // you're running. This means any singletons or global objects you use may
  // suddenly become invalid out from under you. For this reason, it's best to
  // use this only for slow but simple operations like the DNS example.
  CONTINUE_ON_SHUTDOWN,

  // Tasks posted with this mode that have not started executing at
  // shutdown will never run. However, any task that has already begun
  // executing when shutdown is invoked will be allowed to continue and
  // will block shutdown until completion.
  //
  // Note: Because TaskScheduler::Shutdown() may block while these tasks are
  // executing, care must be taken to ensure that they do not block on the
  // thread that called TaskScheduler::Shutdown(), as this may lead to deadlock.
  SKIP_ON_SHUTDOWN,

  // Tasks posted with this mode before shutdown is complete will block shutdown
  // until they're executed. Generally, this should be used only to save
  // critical user data.
  //
  // Note: Tasks with BACKGROUND priority that block shutdown will be promoted
  // to USER_VISIBLE priority during shutdown.
  BLOCK_SHUTDOWN,
};

// Tasks with this trait may block. This includes but is not limited to tasks
// that wait on synchronous file I/O operations: read or write a file from disk,
// interact with a pipe or a socket, rename or delete a file, enumerate files in
// a directory, etc. This trait isn't required for the mere use of locks. For
// tasks that block on base/ synchronization primitives, see the
// WithBaseSyncPrimitives trait.
struct MayBlock {};

// DEPRECATED. Use base::ScopedAllowBaseSyncPrimitives(ForTesting) instead.
//
// Tasks with this trait will pass base::AssertBaseSyncPrimitivesAllowed(), i.e.
// will be allowed on the following methods :
// - base::WaitableEvent::Wait
// - base::ConditionVariable::Wait
// - base::PlatformThread::Join
// - base::PlatformThread::Sleep
// - base::Process::WaitForExit
// - base::Process::WaitForExitWithTimeout
//
// Tasks should generally not use these methods.
//
// Instead of waiting on a WaitableEvent or a ConditionVariable, put the work
// that should happen after the wait in a callback and post that callback from
// where the WaitableEvent or ConditionVariable would have been signaled. If
// something needs to be scheduled after many tasks have executed, use
// base::BarrierClosure.
//
// On Windows, join processes asynchronously using base::win::ObjectWatcher.
//
// MayBlock() must be specified in conjunction with this trait if and only if
// removing usage of methods listed above in the labeled tasks would still
// result in tasks that may block (per MayBlock()'s definition).
//
// In doubt, consult with //base/task_scheduler/OWNERS.
struct WithBaseSyncPrimitives {};

// Describes immutable metadata for a single task or a group of tasks.
class BASE_EXPORT TaskTraits {
 private:
  // ValidTrait ensures TaskTraits' constructor only accepts appropriate types.
  struct ValidTrait {
    ValidTrait(TaskPriority) {}
    ValidTrait(TaskShutdownBehavior) {}
    ValidTrait(MayBlock) {}
    ValidTrait(WithBaseSyncPrimitives) {}
  };

 public:
  // Invoking this constructor without arguments produces TaskTraits that are
  // appropriate for tasks that
  //     (1) don't block (ref. MayBlock() and WithBaseSyncPrimitives()),
  //     (2) prefer inheriting the current priority to specifying their own, and
  //     (3) can either block shutdown or be skipped on shutdown
  //         (TaskScheduler implementation is free to choose a fitting default).
  //
  // To get TaskTraits for tasks that require stricter guarantees and/or know
  // the specific TaskPriority appropriate for them, provide arguments of type
  // TaskPriority, TaskShutdownBehavior, MayBlock, and/or WithBaseSyncPrimitives
  // in any order to the constructor.
  //
  // E.g.
  // constexpr base::TaskTraits default_traits = {};
  // constexpr base::TaskTraits user_visible_traits =
  //     {base::TaskPriority::USER_VISIBLE};
  // constexpr base::TaskTraits user_visible_may_block_traits = {
  //     base::TaskPriority::USER_VISIBLE, base::MayBlock()};
  // constexpr base::TaskTraits other_user_visible_may_block_traits = {
  //     base::MayBlock(), base::TaskPriority::USER_VISIBLE};
  template <class... ArgTypes,
            class CheckArgumentsAreValid = internal::InitTypes<
                decltype(ValidTrait(std::declval<ArgTypes>()))...>>
  constexpr TaskTraits(ArgTypes... args)
      : priority_set_explicitly_(
            internal::HasArgOfType<TaskPriority, ArgTypes...>::value),
        priority_(internal::GetValueFromArgList(
            internal::EnumArgGetter<TaskPriority, TaskPriority::USER_VISIBLE>(),
            args...)),
        shutdown_behavior_set_explicitly_(
            internal::HasArgOfType<TaskShutdownBehavior, ArgTypes...>::value),
        shutdown_behavior_(internal::GetValueFromArgList(
            internal::EnumArgGetter<TaskShutdownBehavior,
                                    TaskShutdownBehavior::SKIP_ON_SHUTDOWN>(),
            args...)),
        may_block_(internal::GetValueFromArgList(
            internal::BooleanArgGetter<MayBlock>(),
            args...)),
        with_base_sync_primitives_(internal::GetValueFromArgList(
            internal::BooleanArgGetter<WithBaseSyncPrimitives>(),
            args...)) {}

  constexpr TaskTraits(const TaskTraits& other) = default;
  TaskTraits& operator=(const TaskTraits& other) = default;

  // Returns TaskTraits constructed by combining |left| and |right|. If a trait
  // is specified in both |left| and |right|, the returned TaskTraits will have
  // the value from |right|.
  static constexpr TaskTraits Override(const TaskTraits& left,
                                       const TaskTraits& right) {
    return TaskTraits(left, right);
  }

  // Returns true if the priority was set explicitly.
  constexpr bool priority_set_explicitly() const {
    return priority_set_explicitly_;
  }

  // Returns the priority of tasks with these traits.
  constexpr TaskPriority priority() const { return priority_; }

  // Returns true if the shutdown behavior was set explicitly.
  constexpr bool shutdown_behavior_set_explicitly() const {
    return shutdown_behavior_set_explicitly_;
  }

  // Returns the shutdown behavior of tasks with these traits.
  constexpr TaskShutdownBehavior shutdown_behavior() const {
    return shutdown_behavior_;
  }

  // Returns true if tasks with these traits may block.
  constexpr bool may_block() const { return may_block_; }

  // Returns true if tasks with these traits may use base/ sync primitives.
  constexpr bool with_base_sync_primitives() const {
    return with_base_sync_primitives_;
  }

 private:
  constexpr TaskTraits(const TaskTraits& left, const TaskTraits& right)
      : priority_set_explicitly_(left.priority_set_explicitly_ ||
                                 right.priority_set_explicitly_),
        priority_(right.priority_set_explicitly_ ? right.priority_
                                                 : left.priority_),
        shutdown_behavior_set_explicitly_(
            left.shutdown_behavior_set_explicitly_ ||
            right.shutdown_behavior_set_explicitly_),
        shutdown_behavior_(right.shutdown_behavior_set_explicitly_
                               ? right.shutdown_behavior_
                               : left.shutdown_behavior_),
        may_block_(left.may_block_ || right.may_block_),
        with_base_sync_primitives_(left.with_base_sync_primitives_ ||
                                   right.with_base_sync_primitives_) {}

  bool priority_set_explicitly_;
  TaskPriority priority_;
  bool shutdown_behavior_set_explicitly_;
  TaskShutdownBehavior shutdown_behavior_;
  bool may_block_;
  bool with_base_sync_primitives_;
};

// Returns string literals for the enums defined in this file. These methods
// should only be used for tracing and debugging.
BASE_EXPORT const char* TaskPriorityToString(TaskPriority task_priority);
BASE_EXPORT const char* TaskShutdownBehaviorToString(
    TaskShutdownBehavior task_priority);

// Stream operators so that the enums defined in this file can be used in
// DCHECK and EXPECT statements.
BASE_EXPORT std::ostream& operator<<(std::ostream& os,
                                     const TaskPriority& shutdown_behavior);
BASE_EXPORT std::ostream& operator<<(
    std::ostream& os,
    const TaskShutdownBehavior& shutdown_behavior);

}  // namespace base

#endif  // BASE_TASK_SCHEDULER_TASK_TRAITS_H_
