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