#ifndef BASE_TASK_SEQUENCE_MANAGER_TASKS_H_
#define BASE_TASK_SEQUENCE_MANAGER_TASKS_H_
#include <optional>
#include <variant>
#include "base/base_export.h"
#include "base/check.h"
#include "base/containers/intrusive_heap.h"
#include "base/dcheck_is_on.h"
#include "base/pending_task.h"
#include "base/task/delay_policy.h"
#include "base/task/sequence_manager/delayed_task_handle_delegate.h"
#include "base/task/sequence_manager/enqueue_order.h"
#include "base/task/sequenced_task_runner.h"
namespace base {
namespace sequence_manager {
using TaskType = uint8_t;
constexpr TaskType kTaskTypeNone = 0;
class TaskOrder;
namespace internal {
struct BASE_EXPORT PostedTask {
PostedTask(scoped_refptr<SequencedTaskRunner> task_runner,
OnceClosure callback,
Location location,
TimeDelta delay = base::TimeDelta(),
Nestable nestable = Nestable::kNestable,
TaskType task_type = kTaskTypeNone,
WeakPtr<DelayedTaskHandleDelegate> delayed_task_handle_delegate =
nullptr);
PostedTask(scoped_refptr<SequencedTaskRunner> task_runner,
OnceClosure callback,
Location location,
TimeTicks delayed_run_time,
subtle::DelayPolicy delay_policy,
Nestable nestable = Nestable::kNestable,
TaskType task_type = kTaskTypeNone,
WeakPtr<DelayedTaskHandleDelegate> delayed_task_handle_delegate =
nullptr);
PostedTask(PostedTask&& move_from) noexcept;
PostedTask(const PostedTask&) = delete;
PostedTask& operator=(const PostedTask&) = delete;
~PostedTask();
bool is_delayed() const {
return std::holds_alternative<TimeTicks>(delay_or_delayed_run_time)
? !std::get<TimeTicks>(delay_or_delayed_run_time).is_null()
: !std::get<TimeDelta>(delay_or_delayed_run_time).is_zero();
}
OnceClosure callback;
Location location;
Nestable nestable = Nestable::kNestable;
TaskType task_type = kTaskTypeNone;
std::variant<TimeDelta, TimeTicks> delay_or_delayed_run_time;
subtle::DelayPolicy delay_policy = subtle::DelayPolicy::kFlexibleNoSooner;
scoped_refptr<SequencedTaskRunner> task_runner;
WeakPtr<DelayedTaskHandleDelegate> delayed_task_handle_delegate;
};
}
struct WakeUp {
TimeTicks time;
TimeDelta leeway;
subtle::DelayPolicy delay_policy = subtle::DelayPolicy::kFlexibleNoSooner;
friend bool operator==(const WakeUp&, const WakeUp&) = default;
bool is_immediate() const { return time.is_null(); }
TimeTicks earliest_time() const;
TimeTicks latest_time() const;
};
struct BASE_EXPORT Task : public PendingTask {
Task(internal::PostedTask posted_task,
EnqueueOrder sequence_order,
EnqueueOrder enqueue_order = EnqueueOrder(),
TimeTicks queue_time = TimeTicks(),
TimeDelta leeway = TimeDelta());
Task(Task&& move_from);
~Task();
Task& operator=(Task&& other);
EnqueueOrder enqueue_order() const {
DCHECK(enqueue_order_);
return enqueue_order_;
}
void set_enqueue_order(EnqueueOrder enqueue_order) {
DCHECK(!enqueue_order_);
enqueue_order_ = enqueue_order;
}
bool enqueue_order_set() const { return enqueue_order_; }
TaskOrder task_order() const;
Nestable nestable = Nestable::kNonNestable;
TaskType task_type;
scoped_refptr<SequencedTaskRunner> task_runner;
#if DCHECK_IS_ON()
bool cross_thread_;
#endif
void SetHeapHandle(HeapHandle heap_handle);
void ClearHeapHandle();
HeapHandle GetHeapHandle() const;
bool IsCanceled() const;
bool WillRunTask();
private:
EnqueueOrder enqueue_order_;
WeakPtr<internal::DelayedTaskHandleDelegate> delayed_task_handle_delegate_;
};
}
}
#endif