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