blob: b773556424494b6cd996c0b244da211dec24aa86 [file] [log] [blame]
// Copyright 2022 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_THREAD_POOL_DELAYED_PRIORITY_QUEUE_H_
#define BASE_TASK_THREAD_POOL_DELAYED_PRIORITY_QUEUE_H_
#include "base/base_export.h"
#include "base/containers/intrusive_heap.h"
#include "base/stl_util.h"
#include "base/task/thread_pool/task_source.h"
#include "base/time/time.h"
namespace base::internal {
// A DelayedPriorityQueue holds TaskSources not ready to run yet. TaskSources
// are ordered by delayed runtime. This class is not thread-safe (requires
// external synchronization).
class BASE_EXPORT DelayedPriorityQueue {
public:
DelayedPriorityQueue();
DelayedPriorityQueue(const DelayedPriorityQueue&) = delete;
DelayedPriorityQueue& operator=(const DelayedPriorityQueue&) = delete;
~DelayedPriorityQueue();
DelayedPriorityQueue& operator=(DelayedPriorityQueue&& other);
// Inserts |task_source| in the DelayedPriorityQueue with |delayed_sort_key|.
void Push(scoped_refptr<TaskSource> task_source, TimeTicks delayed_sort_key);
// Returns a delayed sort key representing the priority of the highest pending
// task in this DelayedPriorityQueue. Cannot be called on an empty
// DelayedPriorityQueue.
const TimeTicks PeekDelayedSortKey() const;
// Returns a pointer to the earliest-to-run TaskSource in this
// DelayedPriorityQueue. Cannot be called on an empty DelayedPriorityQueue.
scoped_refptr<TaskSource> PeekTaskSource() const;
// Removes and returns the highest priority TaskSource in this
// DelayedPriorityQueue. Cannot be called on an empty DelayedPriorityQueue.
scoped_refptr<TaskSource> PopTaskSource();
// Removes |task_source| from the DelayedPriorityQueue. Returns a TaskSource
// which evaluates to true if successful, or false if |task_source| is not
// currently in the DelayedPriorityQueue or the DelayedPriorityQueue is empty.
scoped_refptr<TaskSource> RemoveTaskSource(
scoped_refptr<TaskSource> task_source);
// Updates the delayed sort key of |task_source| to |delayed_sort_key|,
// reordering |task_source| in the queue if necessary. No-ops if the
// TaskSource is not in the DelayedPriorityQueue or the DelayedPriorityQueue
// is empty.
void UpdateDelayedSortKey(scoped_refptr<TaskSource> task_source);
// Returns true if the DelayedPriorityQueue is empty.
bool IsEmpty() const;
// Returns the number of TaskSources in the DelayedPriorityQueue.
size_t Size() const;
// Set the DelayedPriorityQueue to empty all its TaskSources of Tasks when it
// is destroyed; needed to prevent memory leaks caused by a reference cycle
// (TaskSource -> Task -> TaskRunner -> TaskSource...) during test teardown.
void EnableFlushTaskSourcesOnDestroyForTesting();
private:
// A class combining a TaskSource and the delayed_sort_key that determines
// its position in a PriorityQueue.
class TaskSourceAndDelayedSortKey;
struct DelayedPriorityQueueComparisonOperator {
bool operator()(const TaskSourceAndDelayedSortKey& lhs,
const TaskSourceAndDelayedSortKey& rhs) const;
};
using ContainerType = IntrusiveHeap<TaskSourceAndDelayedSortKey,
DelayedPriorityQueueComparisonOperator>;
ContainerType container_;
// Should only be enabled by EnableFlushTaskSourcesOnDestroyForTesting().
bool is_flush_task_sources_on_destroy_enabled_ = false;
};
} // namespace base::internal
#endif // BASE_TASK_THREAD_POOL_DELAYED_PRIORITY_QUEUE_H_