xref: /aosp_15_r20/external/cronet/base/task/sequence_manager/tasks.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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