// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_TASK_SEQUENCE_MANAGER_TASK_QUEUE_IMPL_H_ #define BASE_TASK_SEQUENCE_MANAGER_TASK_QUEUE_IMPL_H_ #include <stddef.h> #include <functional> #include <memory> #include <optional> #include <queue> #include <set> #include <utility> #include <vector> #include "base/base_export.h" #include "base/containers/flat_map.h" #include "base/containers/intrusive_heap.h" #include "base/dcheck_is_on.h" #include "base/functional/callback.h" #include "base/memory/raw_ptr.h" #include "base/memory/raw_ptr_exclusion.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/pending_task.h" #include "base/task/common/checked_lock.h" #include "base/task/common/operations_controller.h" #include "base/task/sequence_manager/associated_thread_id.h" #include "base/task/sequence_manager/atomic_flag_set.h" #include "base/task/sequence_manager/enqueue_order.h" #include "base/task/sequence_manager/fence.h" #include "base/task/sequence_manager/lazily_deallocated_deque.h" #include "base/task/sequence_manager/sequenced_task_source.h" #include "base/task/sequence_manager/task_queue.h" #include "base/task/sequence_manager/tasks.h" #include "base/threading/thread_checker.h" #include "base/time/time_override.h" #include "base/trace_event/base_tracing_forward.h" #include "base/values.h" namespace base { class LazyNow; namespace sequence_manager::internal { class SequenceManagerImpl; class WorkQueue; class WorkQueueSets; class WakeUpQueue; // TaskQueueImpl has four main queues: // // Immediate (non-delayed) tasks: // |immediate_incoming_queue| - PostTask enqueues tasks here. // |immediate_work_queue| - SequenceManager takes immediate tasks here. // // Delayed tasks // |delayed_incoming_queue| - PostDelayedTask enqueues tasks here. // |delayed_work_queue| - SequenceManager takes delayed tasks here. // // The |immediate_incoming_queue| can be accessed from any thread, the other // queues are main-thread only. To reduce the overhead of locking, // |immediate_work_queue| is swapped with |immediate_incoming_queue| when // |immediate_work_queue| becomes empty. // // Delayed tasks are initially posted to |delayed_incoming_queue| and a wake-up // is scheduled with the TimeDomain. When the delay has elapsed, the TimeDomain // calls UpdateDelayedWorkQueue and ready delayed tasks are moved into the // |delayed_work_queue|. Note the EnqueueOrder (used for ordering) for a delayed // task is not set until it's moved into the |delayed_work_queue|. // // TaskQueueImpl uses the WorkQueueSets and the TaskQueueSelector to implement // prioritization. Task selection is done by the TaskQueueSelector and when a // queue is selected, it round-robins between the |immediate_work_queue| and // |delayed_work_queue|. The reason for this is we want to make sure delayed // tasks (normally the most common type) don't starve out immediate work. class BASE_EXPORT TaskQueueImpl : public TaskQueue { … }; } // namespace sequence_manager::internal } // namespace base #endif // BASE_TASK_SEQUENCE_MANAGER_TASK_QUEUE_IMPL_H_