• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_TASK_QUEUE_IMPL_H_
6 #define BASE_TASK_SEQUENCE_MANAGER_TASK_QUEUE_IMPL_H_
7 
8 #include <stddef.h>
9 
10 #include <functional>
11 #include <memory>
12 #include <optional>
13 #include <queue>
14 #include <set>
15 #include <utility>
16 #include <vector>
17 
18 #include "base/base_export.h"
19 #include "base/compiler_specific.h"
20 #include "base/containers/flat_map.h"
21 #include "base/containers/intrusive_heap.h"
22 #include "base/dcheck_is_on.h"
23 #include "base/functional/callback.h"
24 #include "base/memory/raw_ptr.h"
25 #include "base/memory/raw_ptr_exclusion.h"
26 #include "base/memory/scoped_refptr.h"
27 #include "base/memory/weak_ptr.h"
28 #include "base/observer_list.h"
29 #include "base/pending_task.h"
30 #include "base/task/common/checked_lock.h"
31 #include "base/task/common/operations_controller.h"
32 #include "base/task/sequence_manager/associated_thread_id.h"
33 #include "base/task/sequence_manager/atomic_flag_set.h"
34 #include "base/task/sequence_manager/enqueue_order.h"
35 #include "base/task/sequence_manager/fence.h"
36 #include "base/task/sequence_manager/lazily_deallocated_deque.h"
37 #include "base/task/sequence_manager/sequenced_task_source.h"
38 #include "base/task/sequence_manager/task_queue.h"
39 #include "base/task/sequence_manager/tasks.h"
40 #include "base/threading/thread_checker.h"
41 #include "base/time/time_override.h"
42 #include "base/trace_event/base_tracing_forward.h"
43 #include "base/values.h"
44 
45 namespace base {
46 class LazyNow;
47 namespace sequence_manager::internal {
48 
49 class SequenceManagerImpl;
50 class WorkQueue;
51 class WorkQueueSets;
52 class WakeUpQueue;
53 
54 // TaskQueueImpl has four main queues:
55 //
56 // Immediate (non-delayed) tasks:
57 //    |immediate_incoming_queue| - PostTask enqueues tasks here.
58 //    |immediate_work_queue| - SequenceManager takes immediate tasks here.
59 //
60 // Delayed tasks
61 //    |delayed_incoming_queue| - PostDelayedTask enqueues tasks here.
62 //    |delayed_work_queue| - SequenceManager takes delayed tasks here.
63 //
64 // The |immediate_incoming_queue| can be accessed from any thread, the other
65 // queues are main-thread only. To reduce the overhead of locking,
66 // |immediate_work_queue| is swapped with |immediate_incoming_queue| when
67 // |immediate_work_queue| becomes empty.
68 //
69 // Delayed tasks are initially posted to |delayed_incoming_queue| and a wake-up
70 // is scheduled with the TimeDomain.  When the delay has elapsed, the TimeDomain
71 // calls UpdateDelayedWorkQueue and ready delayed tasks are moved into the
72 // |delayed_work_queue|. Note the EnqueueOrder (used for ordering) for a delayed
73 // task is not set until it's moved into the |delayed_work_queue|.
74 //
75 // TaskQueueImpl uses the WorkQueueSets and the TaskQueueSelector to implement
76 // prioritization. Task selection is done by the TaskQueueSelector and when a
77 // queue is selected, it round-robins between the |immediate_work_queue| and
78 // |delayed_work_queue|.  The reason for this is we want to make sure delayed
79 // tasks (normally the most common type) don't starve out immediate work.
80 class BASE_EXPORT TaskQueueImpl : public TaskQueue {
81  public:
82   // Initializes the state of all the task queue features. Must be invoked
83   // after FeatureList initialization and while Chrome is still single-threaded.
84   static void InitializeFeatures();
85 
86   TaskQueueImpl(SequenceManagerImpl* sequence_manager,
87                 WakeUpQueue* wake_up_queue,
88                 const TaskQueue::Spec& spec);
89 
90   TaskQueueImpl(const TaskQueueImpl&) = delete;
91   TaskQueueImpl& operator=(const TaskQueueImpl&) = delete;
92   ~TaskQueueImpl() override;
93 
94   // Types of queues TaskQueueImpl is maintaining internally.
95   enum class WorkQueueType { kImmediate, kDelayed };
96 
97   // Some methods have fast paths when on the main thread.
98   enum class CurrentThread { kMainThread, kNotMainThread };
99 
100   // Non-nestable tasks may get deferred but such queue is being maintained on
101   // SequenceManager side, so we need to keep information how to requeue it.
102   struct DeferredNonNestableTask {
103     Task task;
104 
105     // RAW_PTR_EXCLUSION: Performance reasons (based on analysis of sampling
106     // profiler data and tab_search:top100:2020).
107     RAW_PTR_EXCLUSION internal::TaskQueueImpl* task_queue;
108 
109     WorkQueueType work_queue_type;
110   };
111 
112   using OnNextWakeUpChangedCallback = RepeatingCallback<void(TimeTicks)>;
113   using OnTaskStartedHandler =
114       RepeatingCallback<void(const Task&, const TaskQueue::TaskTiming&)>;
115   using OnTaskCompletedHandler =
116       RepeatingCallback<void(const Task&, TaskQueue::TaskTiming*, LazyNow*)>;
117   using OnTaskPostedHandler = RepeatingCallback<void(const Task&)>;
118   using TaskExecutionTraceLogger =
119       RepeatingCallback<void(perfetto::EventContext&, const Task&)>;
120 
121   // TaskQueue implementation.
122   const char* GetName() const override;
123   bool IsQueueEnabled() const override;
124   bool IsEmpty() const override;
125   size_t GetNumberOfPendingTasks() const override;
126   bool HasTaskToRunImmediatelyOrReadyDelayedTask() const override;
127   std::optional<WakeUp> GetNextDesiredWakeUp() override;
128   void SetQueuePriority(TaskQueue::QueuePriority priority) override;
129   TaskQueue::QueuePriority GetQueuePriority() const override;
130   void AddTaskObserver(TaskObserver* task_observer) override;
131   void RemoveTaskObserver(TaskObserver* task_observer) override;
132   void InsertFence(TaskQueue::InsertFencePosition position) override;
133   void InsertFenceAt(TimeTicks time) override;
134   void RemoveFence() override;
135   bool HasActiveFence() override;
136   bool BlockedByFence() const override;
137   void SetThrottler(TaskQueue::Throttler* throttler) override;
138   void ResetThrottler() override;
139   void UpdateWakeUp(LazyNow* lazy_now) override;
140   void SetShouldReportPostedTasksWhenDisabled(bool should_report) override;
141   scoped_refptr<SingleThreadTaskRunner> CreateTaskRunner(
142       TaskType task_type) const override;
143   const scoped_refptr<SingleThreadTaskRunner>& task_runner() const override;
144   void SetOnTaskStartedHandler(OnTaskStartedHandler handler) override;
145   void SetOnTaskCompletedHandler(OnTaskCompletedHandler handler) override;
146   [[nodiscard]] std::unique_ptr<TaskQueue::OnTaskPostedCallbackHandle>
147   AddOnTaskPostedHandler(OnTaskPostedHandler handler) override;
148   void SetTaskExecutionTraceLogger(TaskExecutionTraceLogger logger) override;
149   std::unique_ptr<QueueEnabledVoter> CreateQueueEnabledVoter() override;
150 
151   void SetQueueEnabled(bool enabled);
152   void UnregisterTaskQueue();
153 
154   QueueName GetProtoName() const;
155 
156   // Returns true if a (potentially hypothetical) task with the specified
157   // |enqueue_order| could run on the queue. Must be called from the main
158   // thread.
159   bool CouldTaskRun(EnqueueOrder enqueue_order) const;
160 
161   // Returns true if a task with |enqueue_order| obtained from this queue was
162   // ever in the queue while it was disabled, blocked by a fence, or less
163   // important than kNormalPriority.
164   bool WasBlockedOrLowPriority(EnqueueOrder enqueue_order) const;
165 
166   // Must only be called from the thread this task queue was created on.
167   void ReloadEmptyImmediateWorkQueue();
168 
169   Value::Dict AsValue(TimeTicks now, bool force_verbose) const;
170 
GetQuiescenceMonitored()171   bool GetQuiescenceMonitored() const { return should_monitor_quiescence_; }
GetShouldNotifyObservers()172   bool GetShouldNotifyObservers() const { return should_notify_observers_; }
173 
174   void NotifyWillProcessTask(const Task& task,
175                              bool was_blocked_or_low_priority);
176   void NotifyDidProcessTask(const Task& task);
177 
178   // Returns true iff this queue has work that can execute now, i.e. immediate
179   // tasks or delayed tasks that have been transferred to the work queue by
180   // MoveReadyDelayedTasksToWorkQueue(). Delayed tasks that are still in the
181   // incoming queue are not taken into account. Ignores the queue's enabled
182   // state and fences.
183   bool HasTaskToRunImmediately() const;
184   bool HasTaskToRunImmediatelyLocked() const
185       EXCLUSIVE_LOCKS_REQUIRED(any_thread_lock_);
186 
has_pending_high_resolution_tasks()187   bool has_pending_high_resolution_tasks() const {
188     return main_thread_only()
189         .delayed_incoming_queue.has_pending_high_resolution_tasks();
190   }
191 
delayed_work_queue()192   WorkQueue* delayed_work_queue() {
193     return main_thread_only().delayed_work_queue.get();
194   }
195 
delayed_work_queue()196   const WorkQueue* delayed_work_queue() const {
197     return main_thread_only().delayed_work_queue.get();
198   }
199 
immediate_work_queue()200   WorkQueue* immediate_work_queue() {
201     return main_thread_only().immediate_work_queue.get();
202   }
203 
immediate_work_queue()204   const WorkQueue* immediate_work_queue() const {
205     return main_thread_only().immediate_work_queue.get();
206   }
207 
task_execution_trace_logger()208   TaskExecutionTraceLogger task_execution_trace_logger() const {
209     return main_thread_only().task_execution_trace_logger;
210   }
211 
212   // Removes all canceled tasks from the front of the delayed incoming queue.
213   // After calling this, GetNextDesiredWakeUp() is guaranteed to return a time
214   // for a non-canceled task, if one exists. Return true if a canceled task was
215   // removed.
216   bool RemoveAllCanceledDelayedTasksFromFront(LazyNow* lazy_now);
217 
218   // Enqueues in `delayed_work_queue` all delayed tasks which must run now
219   // (cannot be postponed) and possibly some delayed tasks which can run now but
220   // could be postponed (due to how tasks are stored, it is not possible to
221   // retrieve all such tasks efficiently). Must be called from the main thread.
222   void MoveReadyDelayedTasksToWorkQueue(LazyNow* lazy_now,
223                                         EnqueueOrder enqueue_order);
224 
225   void OnWakeUp(LazyNow* lazy_now, EnqueueOrder enqueue_order);
226 
wake_up_queue()227   const WakeUpQueue* wake_up_queue() const {
228     return main_thread_only().wake_up_queue;
229   }
230 
heap_handle()231   HeapHandle heap_handle() const { return main_thread_only().heap_handle; }
232 
set_heap_handle(HeapHandle heap_handle)233   void set_heap_handle(HeapHandle heap_handle) {
234     main_thread_only().heap_handle = heap_handle;
235   }
236 
237   // Pushes |task| onto the front of the specified work queue. Caution must be
238   // taken with this API because you could easily starve out other work.
239   // TODO(kraynov): Simplify non-nestable task logic https://crbug.com/845437.
240   void RequeueDeferredNonNestableTask(DeferredNonNestableTask task);
241 
242   void PushImmediateIncomingTaskForTest(Task task);
243 
244   // Iterates over |delayed_incoming_queue| removing canceled tasks. In
245   // addition MaybeShrinkQueue is called on all internal queues.
246   void ReclaimMemory(TimeTicks now);
247 
248   void OnTaskStarted(const Task& task,
249                      const TaskQueue::TaskTiming& task_timing);
250   void OnTaskCompleted(const Task& task,
251                        TaskQueue::TaskTiming* task_timing,
252                        LazyNow* lazy_now);
253   bool RequiresTaskTiming() const;
254 
255   WeakPtr<SequenceManagerImpl> GetSequenceManagerWeakPtr();
256 
sequence_manager()257   SequenceManagerImpl* sequence_manager() const { return sequence_manager_; }
258 
259   // Returns true if this queue is unregistered or task queue manager is deleted
260   // and this queue can be safely deleted on any thread.
261   bool IsUnregistered() const;
262 
263   // Called by the associated sequence manager when it becomes bound. Updates
264   // the weak pointer stored in voters with one bound to the correct thread.
265   void CompleteInitializationOnBoundThread();
266 
267   void AddQueueEnabledVoter(bool voter_is_enabled,
268                             TaskQueue::QueueEnabledVoter& voter);
269   void RemoveQueueEnabledVoter(bool voter_is_enabled,
270                                TaskQueue::QueueEnabledVoter& voter);
271   void OnQueueEnabledVoteChanged(bool enabled);
272 
273  protected:
274   // Sets this queue's next wake up time to |wake_up| in the time domain.
275   void SetNextWakeUp(LazyNow* lazy_now, std::optional<WakeUp> wake_up);
276 
277  private:
278   friend class WorkQueue;
279   friend class WorkQueueTest;
280   friend class DelayedTaskHandleDelegate;
281 
282   // A TaskQueueImpl instance can be destroyed or unregistered before all its
283   // associated TaskRunner instances are (they are refcounted). Thus we need a
284   // way to prevent TaskRunner instances from posting further tasks. This class
285   // guards PostTask calls using an OperationsController.
286   // This class is ref-counted as both the TaskQueueImpl instance and all
287   // associated TaskRunner instances share the same GuardedTaskPoster instance.
288   // When TaskQueueImpl shuts down it calls ShutdownAndWaitForZeroOperations(),
289   // preventing further PostTask calls being made to the underlying
290   // TaskQueueImpl.
291   class GuardedTaskPoster : public RefCountedThreadSafe<GuardedTaskPoster> {
292    public:
293     explicit GuardedTaskPoster(TaskQueueImpl* outer);
294 
295     bool PostTask(PostedTask task);
296     DelayedTaskHandle PostCancelableTask(PostedTask task);
297     bool RunOrPostTask(PostedTask task);
298 
StartAcceptingOperations()299     void StartAcceptingOperations() {
300       operations_controller_.StartAcceptingOperations();
301     }
302 
ShutdownAndWaitForZeroOperations()303     void ShutdownAndWaitForZeroOperations() {
304       operations_controller_.ShutdownAndWaitForZeroOperations();
305       // `operations_controller_` won't let any more operations here, and
306       // `outer_` might get destroyed before `this` does, so clearing `outer_`
307       // avoids a potential dangling pointer.
308       outer_ = nullptr;
309     }
310 
311    private:
312     friend class RefCountedThreadSafe<GuardedTaskPoster>;
313 
314     ~GuardedTaskPoster();
315 
316     base::internal::OperationsController operations_controller_;
317     // Pointer might be stale, access guarded by |operations_controller_|
318     // RAW_PTR_EXCLUSION: Performance reasons (based on analysis of
319     // speedometer3).
320     RAW_PTR_EXCLUSION TaskQueueImpl* outer_ = nullptr;
321   };
322 
323   class TaskRunner final : public SingleThreadTaskRunner {
324    public:
325     explicit TaskRunner(scoped_refptr<GuardedTaskPoster> task_poster,
326                         scoped_refptr<AssociatedThreadId> associated_thread,
327                         TaskType task_type);
328 
329     bool PostDelayedTask(const Location& location,
330                          OnceClosure callback,
331                          TimeDelta delay) final;
332     bool PostDelayedTaskAt(subtle::PostDelayedTaskPassKey,
333                            const Location& location,
334                            OnceClosure callback,
335                            TimeTicks delayed_run_time,
336                            base::subtle::DelayPolicy delay_policy) final;
337     DelayedTaskHandle PostCancelableDelayedTaskAt(
338         subtle::PostDelayedTaskPassKey,
339         const Location& location,
340         OnceClosure callback,
341         TimeTicks delayed_run_time,
342         base::subtle::DelayPolicy delay_policy) final;
343     DelayedTaskHandle PostCancelableDelayedTask(subtle::PostDelayedTaskPassKey,
344                                                 const Location& location,
345                                                 OnceClosure callback,
346                                                 TimeDelta delay) final;
347     bool PostNonNestableDelayedTask(const Location& location,
348                                     OnceClosure callback,
349                                     TimeDelta delay) final;
350     bool RunOrPostTask(subtle::RunOrPostTaskPassKey,
351                        const Location& from_here,
352                        OnceClosure task) final;
353     bool BelongsToCurrentThread() const final;
354     bool RunsTasksInCurrentSequence() const final;
355 
356    private:
357     ~TaskRunner() final;
358 
359     const scoped_refptr<GuardedTaskPoster> task_poster_;
360     const scoped_refptr<AssociatedThreadId> associated_thread_;
361     const TaskType task_type_;
362   };
363 
364   class OnTaskPostedCallbackHandleImpl
365       : public TaskQueue::OnTaskPostedCallbackHandle {
366    public:
367     OnTaskPostedCallbackHandleImpl(
368         TaskQueueImpl* task_queue_impl,
369         scoped_refptr<const AssociatedThreadId> associated_thread_);
370     ~OnTaskPostedCallbackHandleImpl() override;
371 
372     // Callback handles can outlive the associated TaskQueueImpl, so the
373     // reference needs to be cleared when the queue is unregistered.
UnregisterTaskQueue()374     void UnregisterTaskQueue() { task_queue_impl_ = nullptr; }
375 
376    private:
377     // RAW_PTR_EXCLUSION: Performance reasons (based on analysis of
378     // speedometer3).
379     RAW_PTR_EXCLUSION TaskQueueImpl* task_queue_impl_ = nullptr;
380     const scoped_refptr<const AssociatedThreadId> associated_thread_;
381   };
382 
383   // A queue for holding delayed tasks before their delay has expired.
384   struct DelayedIncomingQueue {
385    public:
386     DelayedIncomingQueue();
387     DelayedIncomingQueue(const DelayedIncomingQueue&) = delete;
388     DelayedIncomingQueue& operator=(const DelayedIncomingQueue&) = delete;
389     ~DelayedIncomingQueue();
390 
391     void push(Task task);
392     void remove(HeapHandle heap_handle);
393     Task take_top();
emptyDelayedIncomingQueue394     bool empty() const { return queue_.empty(); }
sizeDelayedIncomingQueue395     size_t size() const { return queue_.size(); }
topDelayedIncomingQueue396     const Task& top() const LIFETIME_BOUND { return queue_.top(); }
397     void swap(DelayedIncomingQueue* other);
398 
has_pending_high_resolution_tasksDelayedIncomingQueue399     bool has_pending_high_resolution_tasks() const {
400       return pending_high_res_tasks_;
401     }
402 
403     // TODO(crbug.com/40735653): we pass SequenceManager to be able to record
404     // crash keys. Remove this parameter after chasing down this crash.
405     void SweepCancelledTasks(SequenceManagerImpl* sequence_manager);
406     Value::List AsValue(TimeTicks now) const;
407 
408    private:
409     struct Compare {
410       bool operator()(const Task& lhs, const Task& rhs) const;
411     };
412     IntrusiveHeap<Task, Compare> queue_;
413 
414     // Number of pending tasks in the queue that need high resolution timing.
415     int pending_high_res_tasks_ = 0;
416   };
417 
418   struct MainThreadOnly {
419     MainThreadOnly(TaskQueueImpl* task_queue, WakeUpQueue* wake_up_queue);
420     ~MainThreadOnly();
421 
422     raw_ptr<WakeUpQueue> wake_up_queue;
423 
424     raw_ptr<TaskQueue::Throttler> throttler = nullptr;
425 
426     std::unique_ptr<WorkQueue> delayed_work_queue;
427     std::unique_ptr<WorkQueue> immediate_work_queue;
428     DelayedIncomingQueue delayed_incoming_queue;
429     ObserverList<TaskObserver>::UncheckedAndDanglingUntriaged task_observers;
430     HeapHandle heap_handle;
431     bool is_enabled = true;
432     std::optional<Fence> current_fence;
433     std::optional<TimeTicks> delayed_fence;
434     // Snapshots the next sequence number when the queue is unblocked, otherwise
435     // it contains EnqueueOrder::none(). If the EnqueueOrder of a task just
436     // popped from this queue is greater than this, it means that the queue was
437     // never disabled or blocked by a fence while the task was queued.
438     EnqueueOrder enqueue_order_at_which_we_became_unblocked;
439     // If the EnqueueOrder of a task just popped from this queue is greater than
440     // this, it means that the queue was never disabled, blocked by a fence or
441     // less important than kNormalPriority while the task was queued.
442     //
443     // Implementation details:
444     // 1) When the queue is made less important than kNormalPriority, this is
445     //    set to EnqueueOrder::max(). The EnqueueOrder of any task will compare
446     //    less than this.
447     // 2) When the queue is made at least as important as kNormalPriority, this
448     //    snapshots the next sequence number. If the queue is blocked, the value
449     //    is irrelevant because no task should be popped. If the queue is not
450     //    blocked, the EnqueueOrder of any already queued task will compare less
451     //    than this.
452     // 3) When the queue is unblocked while at least as important as
453     //    kNormalPriority, this snapshots the next sequence number. The
454     //    EnqueueOrder of any already queued task will compare less than this.
455     //
456     // TODO(crbug.com/40791504): Change this to use `TaskOrder`.
457     EnqueueOrder
458         enqueue_order_at_which_we_became_unblocked_with_normal_priority;
459     OnTaskStartedHandler on_task_started_handler;
460     OnTaskCompletedHandler on_task_completed_handler;
461     TaskExecutionTraceLogger task_execution_trace_logger;
462     // Last reported wake up, used only in UpdateWakeUp to avoid
463     // excessive calls.
464     std::optional<WakeUp> scheduled_wake_up;
465     // If false, queue will be disabled. Used only for tests.
466     bool is_enabled_for_test = true;
467     // The time at which the task queue was disabled, if it is currently
468     // disabled.
469     std::optional<TimeTicks> disabled_time;
470     // Whether or not the task queue should emit tracing events for tasks
471     // posted to this queue when it is disabled.
472     bool should_report_posted_tasks_when_disabled = false;
473 
474     int enabled_voter_count = 0;
475     int voter_count = 0;
476   };
477 
478   void PostTask(PostedTask task);
479   void RemoveCancelableTask(HeapHandle heap_handle);
480 
481   void PostImmediateTaskImpl(PostedTask task, CurrentThread current_thread);
482   void PostDelayedTaskImpl(PostedTask task, CurrentThread current_thread);
483 
484   // Push the task onto the |delayed_incoming_queue|. Lock-free main thread
485   // only fast path.
486   void PushOntoDelayedIncomingQueueFromMainThread(Task pending_task,
487                                                   LazyNow* lazy_now,
488                                                   bool notify_task_annotator);
489 
490   // Push the task onto the |delayed_incoming_queue|.  Slow path from other
491   // threads.
492   void PushOntoDelayedIncomingQueue(Task pending_task);
493 
494   void ScheduleDelayedWorkTask(Task pending_task);
495 
496   void MoveReadyImmediateTasksToImmediateWorkQueueLocked()
497       EXCLUSIVE_LOCKS_REQUIRED(any_thread_lock_);
498 
499   // LazilyDeallocatedDeque use TimeTicks to figure out when to resize.  We
500   // should use real time here always.
501   using TaskDeque =
502       LazilyDeallocatedDeque<Task, subtle::TimeTicksNowIgnoringOverride>;
503 
504   // Extracts all the tasks from the immediate incoming queue and swaps it with
505   // |queue| which must be empty.
506   // Can be called from any thread.
507   void TakeImmediateIncomingQueueTasks(TaskDeque* queue);
508 
509   void TraceQueueSize() const;
510   static Value::List QueueAsValue(const TaskDeque& queue, TimeTicks now);
511   static Value::Dict TaskAsValue(const Task& task, TimeTicks now);
512 
513   // Returns a Task representation for `delayed_task`.
514   Task MakeDelayedTask(PostedTask delayed_task, LazyNow* lazy_now) const;
515 
516   // Activate a delayed fence if a time has come based on `task`'s delayed run
517   // time.
518   void ActivateDelayedFenceIfNeeded(const Task& task);
519 
520   // Updates state protected by any_thread_lock_.
521   void UpdateCrossThreadQueueStateLocked()
522       EXCLUSIVE_LOCKS_REQUIRED(any_thread_lock_);
523 
524   TimeDelta GetTaskDelayAdjustment(CurrentThread current_thread);
525 
526   // Reports the task if it was due to IPC and was posted to a disabled queue.
527   // This should be called after WillQueueTask has been called for the task.
528   void MaybeReportIpcTaskQueuedFromMainThread(const Task& pending_task);
529   bool ShouldReportIpcTaskQueuedFromAnyThreadLocked(
530       base::TimeDelta* time_since_disabled)
531       EXCLUSIVE_LOCKS_REQUIRED(any_thread_lock_);
532   void MaybeReportIpcTaskQueuedFromAnyThreadLocked(const Task& pending_task)
533       EXCLUSIVE_LOCKS_REQUIRED(any_thread_lock_);
534   void MaybeReportIpcTaskQueuedFromAnyThreadUnlocked(const Task& pending_task);
535   void ReportIpcTaskQueued(const Task& pending_task,
536                            const base::TimeDelta& time_since_disabled);
537 
538   // Invoked when the queue becomes enabled and not blocked by a fence.
539   void OnQueueUnblocked();
540 
541   void InsertFence(Fence fence);
542 
543   void RemoveOnTaskPostedHandler(
544       OnTaskPostedCallbackHandleImpl* on_task_posted_callback_handle);
545 
546   TaskQueue::QueuePriority DefaultPriority() const;
547 
AreAllQueueEnabledVotersEnabled()548   bool AreAllQueueEnabledVotersEnabled() const {
549     return main_thread_only().enabled_voter_count ==
550            main_thread_only().voter_count;
551   }
552 
553   // Returns whether the queue is enabled. May be invoked from any thread.
554   bool IsQueueEnabledFromAnyThread() const;
555 
556   QueueName name_;
557   const raw_ptr<SequenceManagerImpl, AcrossTasksDanglingUntriaged>
558       sequence_manager_;
559 
560   const scoped_refptr<AssociatedThreadId> associated_thread_;
561 
562   const scoped_refptr<GuardedTaskPoster> task_poster_;
563 
564   mutable base::internal::CheckedLock any_thread_lock_;
565 
566   struct AnyThread {
567     // Mirrored from MainThreadOnly. These are only used for tracing.
568     struct TracingOnly {
569       TracingOnly();
570       ~TracingOnly();
571 
572       std::optional<TimeTicks> disabled_time;
573       bool should_report_posted_tasks_when_disabled = false;
574     };
575 
576     AnyThread();
577     ~AnyThread();
578 
579     TaskDeque immediate_incoming_queue;
580 
581     bool immediate_work_queue_empty = true;
582     bool post_immediate_task_should_schedule_work = true;
583     bool unregistered = false;
584     bool is_enabled = true;
585 
586     base::flat_map<raw_ptr<OnTaskPostedCallbackHandleImpl>, OnTaskPostedHandler>
587         on_task_posted_handlers;
588 
589 #if DCHECK_IS_ON()
590     // A cache of |immediate_work_queue->work_queue_set_index()| which is used
591     // to index into
592     // SequenceManager::Settings::per_priority_cross_thread_task_delay to apply
593     // a priority specific delay for debugging purposes.
594     size_t queue_set_index = 0;
595 #endif
596 
597     TracingOnly tracing_only;
598   };
599 
600   AnyThread any_thread_ GUARDED_BY(any_thread_lock_);
601 
602   MainThreadOnly main_thread_only_;
main_thread_only()603   MainThreadOnly& main_thread_only() {
604     associated_thread_->AssertInSequenceWithCurrentThread();
605     return main_thread_only_;
606   }
main_thread_only()607   const MainThreadOnly& main_thread_only() const LIFETIME_BOUND {
608     associated_thread_->AssertInSequenceWithCurrentThread();
609     return main_thread_only_;
610   }
611 
612   // Handle to our entry within the SequenceManagers |empty_queues_to_reload_|
613   // atomic flag set. Used to signal that this queue needs to be reloaded.
614   // If you call SetActive(false) you should do so inside |any_thread_lock_|
615   // because there is a danger a cross thread PostTask might reset it before we
616   // make |immediate_work_queue| non-empty.
617   AtomicFlagSet::AtomicFlag empty_queues_to_reload_handle_;
618 
619   const bool should_monitor_quiescence_;
620   const bool should_notify_observers_;
621   const bool delayed_fence_allowed_;
622 
623   const scoped_refptr<SingleThreadTaskRunner> default_task_runner_;
624 
625   base::WeakPtrFactory<TaskQueueImpl> voter_weak_ptr_factory_{this};
626 };
627 
628 }  // namespace sequence_manager::internal
629 }  // namespace base
630 
631 #endif  // BASE_TASK_SEQUENCE_MANAGER_TASK_QUEUE_IMPL_H_
632