1*6777b538SAndroid Build Coastguard Worker // Copyright 2018 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_TASK_SEQUENCE_MANAGER_TASKS_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_TASK_SEQUENCE_MANAGER_TASKS_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <optional> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 11*6777b538SAndroid Build Coastguard Worker #include "base/check.h" 12*6777b538SAndroid Build Coastguard Worker #include "base/containers/intrusive_heap.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/dcheck_is_on.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/pending_task.h" 15*6777b538SAndroid Build Coastguard Worker #include "base/task/delay_policy.h" 16*6777b538SAndroid Build Coastguard Worker #include "base/task/sequence_manager/delayed_task_handle_delegate.h" 17*6777b538SAndroid Build Coastguard Worker #include "base/task/sequence_manager/enqueue_order.h" 18*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner.h" 19*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/types/variant.h" 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker namespace base { 22*6777b538SAndroid Build Coastguard Worker namespace sequence_manager { 23*6777b538SAndroid Build Coastguard Worker 24*6777b538SAndroid Build Coastguard Worker using TaskType = uint8_t; 25*6777b538SAndroid Build Coastguard Worker constexpr TaskType kTaskTypeNone = 0; 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker class TaskOrder; 28*6777b538SAndroid Build Coastguard Worker 29*6777b538SAndroid Build Coastguard Worker namespace internal { 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Worker // Wrapper around PostTask method arguments and the assigned task type. 32*6777b538SAndroid Build Coastguard Worker // Eventually it becomes a PendingTask once accepted by a TaskQueueImpl. 33*6777b538SAndroid Build Coastguard Worker struct BASE_EXPORT PostedTask { 34*6777b538SAndroid Build Coastguard Worker explicit PostedTask(scoped_refptr<SequencedTaskRunner> task_runner, 35*6777b538SAndroid Build Coastguard Worker OnceClosure callback, 36*6777b538SAndroid Build Coastguard Worker Location location, 37*6777b538SAndroid Build Coastguard Worker TimeDelta delay = base::TimeDelta(), 38*6777b538SAndroid Build Coastguard Worker Nestable nestable = Nestable::kNestable, 39*6777b538SAndroid Build Coastguard Worker TaskType task_type = kTaskTypeNone, 40*6777b538SAndroid Build Coastguard Worker WeakPtr<DelayedTaskHandleDelegate> 41*6777b538SAndroid Build Coastguard Worker delayed_task_handle_delegate = nullptr); 42*6777b538SAndroid Build Coastguard Worker explicit PostedTask(scoped_refptr<SequencedTaskRunner> task_runner, 43*6777b538SAndroid Build Coastguard Worker OnceClosure callback, 44*6777b538SAndroid Build Coastguard Worker Location location, 45*6777b538SAndroid Build Coastguard Worker TimeTicks delayed_run_time, 46*6777b538SAndroid Build Coastguard Worker subtle::DelayPolicy delay_policy, 47*6777b538SAndroid Build Coastguard Worker Nestable nestable = Nestable::kNestable, 48*6777b538SAndroid Build Coastguard Worker TaskType task_type = kTaskTypeNone, 49*6777b538SAndroid Build Coastguard Worker WeakPtr<DelayedTaskHandleDelegate> 50*6777b538SAndroid Build Coastguard Worker delayed_task_handle_delegate = nullptr); 51*6777b538SAndroid Build Coastguard Worker PostedTask(PostedTask&& move_from) noexcept; 52*6777b538SAndroid Build Coastguard Worker PostedTask(const PostedTask&) = delete; 53*6777b538SAndroid Build Coastguard Worker PostedTask& operator=(const PostedTask&) = delete; 54*6777b538SAndroid Build Coastguard Worker ~PostedTask(); 55*6777b538SAndroid Build Coastguard Worker is_delayedPostedTask56*6777b538SAndroid Build Coastguard Worker bool is_delayed() const { 57*6777b538SAndroid Build Coastguard Worker return absl::holds_alternative<TimeTicks>(delay_or_delayed_run_time) 58*6777b538SAndroid Build Coastguard Worker ? !absl::get<TimeTicks>(delay_or_delayed_run_time).is_null() 59*6777b538SAndroid Build Coastguard Worker : !absl::get<TimeDelta>(delay_or_delayed_run_time).is_zero(); 60*6777b538SAndroid Build Coastguard Worker } 61*6777b538SAndroid Build Coastguard Worker 62*6777b538SAndroid Build Coastguard Worker OnceClosure callback; 63*6777b538SAndroid Build Coastguard Worker Location location; 64*6777b538SAndroid Build Coastguard Worker Nestable nestable = Nestable::kNestable; 65*6777b538SAndroid Build Coastguard Worker TaskType task_type = kTaskTypeNone; 66*6777b538SAndroid Build Coastguard Worker absl::variant<TimeDelta, TimeTicks> delay_or_delayed_run_time; 67*6777b538SAndroid Build Coastguard Worker subtle::DelayPolicy delay_policy = subtle::DelayPolicy::kFlexibleNoSooner; 68*6777b538SAndroid Build Coastguard Worker // The task runner this task is running on. Can be used by task runners that 69*6777b538SAndroid Build Coastguard Worker // support posting back to the "current sequence". 70*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner; 71*6777b538SAndroid Build Coastguard Worker // The delegate for the DelayedTaskHandle, if this task was posted through 72*6777b538SAndroid Build Coastguard Worker // PostCancelableDelayedTask(), nullptr otherwise. 73*6777b538SAndroid Build Coastguard Worker WeakPtr<DelayedTaskHandleDelegate> delayed_task_handle_delegate; 74*6777b538SAndroid Build Coastguard Worker }; 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker } // namespace internal 77*6777b538SAndroid Build Coastguard Worker 78*6777b538SAndroid Build Coastguard Worker enum class WakeUpResolution { kLow, kHigh }; 79*6777b538SAndroid Build Coastguard Worker 80*6777b538SAndroid Build Coastguard Worker // Represents a time at which a task wants to run. 81*6777b538SAndroid Build Coastguard Worker struct WakeUp { 82*6777b538SAndroid Build Coastguard Worker // is_null() for immediate wake up. 83*6777b538SAndroid Build Coastguard Worker TimeTicks time; 84*6777b538SAndroid Build Coastguard Worker // These are meaningless if is_immediate(). 85*6777b538SAndroid Build Coastguard Worker TimeDelta leeway; 86*6777b538SAndroid Build Coastguard Worker WakeUpResolution resolution = WakeUpResolution::kLow; 87*6777b538SAndroid Build Coastguard Worker subtle::DelayPolicy delay_policy = subtle::DelayPolicy::kFlexibleNoSooner; 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker bool operator!=(const WakeUp& other) const { 90*6777b538SAndroid Build Coastguard Worker return time != other.time || leeway != other.leeway || 91*6777b538SAndroid Build Coastguard Worker resolution != other.resolution || delay_policy != other.delay_policy; 92*6777b538SAndroid Build Coastguard Worker } 93*6777b538SAndroid Build Coastguard Worker 94*6777b538SAndroid Build Coastguard Worker bool operator==(const WakeUp& other) const { return !(*this != other); } 95*6777b538SAndroid Build Coastguard Worker is_immediateWakeUp96*6777b538SAndroid Build Coastguard Worker bool is_immediate() const { return time.is_null(); } 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Worker TimeTicks earliest_time() const; 99*6777b538SAndroid Build Coastguard Worker TimeTicks latest_time() const; 100*6777b538SAndroid Build Coastguard Worker }; 101*6777b538SAndroid Build Coastguard Worker 102*6777b538SAndroid Build Coastguard Worker // PendingTask with extra metadata for SequenceManager. 103*6777b538SAndroid Build Coastguard Worker struct BASE_EXPORT Task : public PendingTask { 104*6777b538SAndroid Build Coastguard Worker Task(internal::PostedTask posted_task, 105*6777b538SAndroid Build Coastguard Worker EnqueueOrder sequence_order, 106*6777b538SAndroid Build Coastguard Worker EnqueueOrder enqueue_order = EnqueueOrder(), 107*6777b538SAndroid Build Coastguard Worker TimeTicks queue_time = TimeTicks(), 108*6777b538SAndroid Build Coastguard Worker WakeUpResolution wake_up_resolution = WakeUpResolution::kLow, 109*6777b538SAndroid Build Coastguard Worker TimeDelta leeway = TimeDelta()); 110*6777b538SAndroid Build Coastguard Worker Task(Task&& move_from); 111*6777b538SAndroid Build Coastguard Worker ~Task(); 112*6777b538SAndroid Build Coastguard Worker Task& operator=(Task&& other); 113*6777b538SAndroid Build Coastguard Worker 114*6777b538SAndroid Build Coastguard Worker // SequenceManager is particularly sensitive to enqueue order, 115*6777b538SAndroid Build Coastguard Worker // so we have accessors for safety. enqueue_orderTask116*6777b538SAndroid Build Coastguard Worker EnqueueOrder enqueue_order() const { 117*6777b538SAndroid Build Coastguard Worker DCHECK(enqueue_order_); 118*6777b538SAndroid Build Coastguard Worker return enqueue_order_; 119*6777b538SAndroid Build Coastguard Worker } 120*6777b538SAndroid Build Coastguard Worker set_enqueue_orderTask121*6777b538SAndroid Build Coastguard Worker void set_enqueue_order(EnqueueOrder enqueue_order) { 122*6777b538SAndroid Build Coastguard Worker DCHECK(!enqueue_order_); 123*6777b538SAndroid Build Coastguard Worker enqueue_order_ = enqueue_order; 124*6777b538SAndroid Build Coastguard Worker } 125*6777b538SAndroid Build Coastguard Worker enqueue_order_setTask126*6777b538SAndroid Build Coastguard Worker bool enqueue_order_set() const { return enqueue_order_; } 127*6777b538SAndroid Build Coastguard Worker 128*6777b538SAndroid Build Coastguard Worker TaskOrder task_order() const; 129*6777b538SAndroid Build Coastguard Worker 130*6777b538SAndroid Build Coastguard Worker // OK to dispatch from a nested loop. 131*6777b538SAndroid Build Coastguard Worker Nestable nestable = Nestable::kNonNestable; 132*6777b538SAndroid Build Coastguard Worker 133*6777b538SAndroid Build Coastguard Worker // Needs high resolution timers. 134*6777b538SAndroid Build Coastguard Worker bool is_high_res = false; 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard Worker TaskType task_type; 137*6777b538SAndroid Build Coastguard Worker 138*6777b538SAndroid Build Coastguard Worker // The task runner this task is running on. Can be used by task runners that 139*6777b538SAndroid Build Coastguard Worker // support posting back to the "current sequence". 140*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner; 141*6777b538SAndroid Build Coastguard Worker 142*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 143*6777b538SAndroid Build Coastguard Worker bool cross_thread_; 144*6777b538SAndroid Build Coastguard Worker #endif 145*6777b538SAndroid Build Coastguard Worker 146*6777b538SAndroid Build Coastguard Worker // Implement the intrusive heap contract. 147*6777b538SAndroid Build Coastguard Worker void SetHeapHandle(HeapHandle heap_handle); 148*6777b538SAndroid Build Coastguard Worker void ClearHeapHandle(); 149*6777b538SAndroid Build Coastguard Worker HeapHandle GetHeapHandle() const; 150*6777b538SAndroid Build Coastguard Worker 151*6777b538SAndroid Build Coastguard Worker // Returns true if this task was canceled, either through weak pointer 152*6777b538SAndroid Build Coastguard Worker // invalidation or through |delayed_task_handle_delegate_|. 153*6777b538SAndroid Build Coastguard Worker bool IsCanceled() const; 154*6777b538SAndroid Build Coastguard Worker 155*6777b538SAndroid Build Coastguard Worker // Must be invoked before running the task. Returns true if the task must run 156*6777b538SAndroid Build Coastguard Worker // (any delayed task handle will have been invalidated by this method), false 157*6777b538SAndroid Build Coastguard Worker // if it mustn't run (e.g. delayed task handle was invalidated prior to 158*6777b538SAndroid Build Coastguard Worker // calling this method). 159*6777b538SAndroid Build Coastguard Worker bool WillRunTask(); 160*6777b538SAndroid Build Coastguard Worker 161*6777b538SAndroid Build Coastguard Worker private: 162*6777b538SAndroid Build Coastguard Worker // `enqueue_order_` is the primary component used to order tasks (see 163*6777b538SAndroid Build Coastguard Worker // `TaskOrder`). For immediate tasks, `enqueue_order` is set when posted, but 164*6777b538SAndroid Build Coastguard Worker // for delayed tasks it's not defined until they are enqueued. This is because 165*6777b538SAndroid Build Coastguard Worker // otherwise delayed tasks could run before an immediate task posted after the 166*6777b538SAndroid Build Coastguard Worker // delayed task. 167*6777b538SAndroid Build Coastguard Worker EnqueueOrder enqueue_order_; 168*6777b538SAndroid Build Coastguard Worker 169*6777b538SAndroid Build Coastguard Worker // The delegate for the DelayedTaskHandle, if this task was posted through 170*6777b538SAndroid Build Coastguard Worker // `PostCancelableDelayedTask()`, not set otherwise. The task is canceled if 171*6777b538SAndroid Build Coastguard Worker // `WeakPtr::WasInvalidated` is true. Note: if the task was not posted via 172*6777b538SAndroid Build Coastguard Worker // `PostCancelableDelayedTask()`. the weak pointer won't be valid, but 173*6777b538SAndroid Build Coastguard Worker // `WeakPtr::WasInvalidated` will be false. 174*6777b538SAndroid Build Coastguard Worker WeakPtr<internal::DelayedTaskHandleDelegate> delayed_task_handle_delegate_; 175*6777b538SAndroid Build Coastguard Worker }; 176*6777b538SAndroid Build Coastguard Worker 177*6777b538SAndroid Build Coastguard Worker } // namespace sequence_manager 178*6777b538SAndroid Build Coastguard Worker } // namespace base 179*6777b538SAndroid Build Coastguard Worker 180*6777b538SAndroid Build Coastguard Worker #endif // BASE_TASK_SEQUENCE_MANAGER_TASKS_H_ 181