xref: /aosp_15_r20/external/cronet/base/task/thread_pool/delayed_priority_queue.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 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_THREAD_POOL_DELAYED_PRIORITY_QUEUE_H_
6 #define BASE_TASK_THREAD_POOL_DELAYED_PRIORITY_QUEUE_H_
7 
8 #include "base/base_export.h"
9 #include "base/containers/intrusive_heap.h"
10 #include "base/stl_util.h"
11 #include "base/task/thread_pool/task_source.h"
12 #include "base/time/time.h"
13 
14 namespace base::internal {
15 
16 // A DelayedPriorityQueue holds TaskSources not ready to run yet. TaskSources
17 // are ordered by delayed runtime. This class is not thread-safe (requires
18 // external synchronization).
19 class BASE_EXPORT DelayedPriorityQueue {
20  public:
21   DelayedPriorityQueue();
22   DelayedPriorityQueue(const DelayedPriorityQueue&) = delete;
23   DelayedPriorityQueue& operator=(const DelayedPriorityQueue&) = delete;
24   ~DelayedPriorityQueue();
25 
26   DelayedPriorityQueue& operator=(DelayedPriorityQueue&& other);
27 
28   // Inserts |task_source| in the DelayedPriorityQueue with |delayed_sort_key|.
29   void Push(scoped_refptr<TaskSource> task_source, TimeTicks delayed_sort_key);
30 
31   // Returns a delayed sort key representing the priority of the highest pending
32   // task in this DelayedPriorityQueue. Cannot be called on an empty
33   // DelayedPriorityQueue.
34   const TimeTicks PeekDelayedSortKey() const;
35 
36   // Returns a pointer to the earliest-to-run TaskSource in this
37   // DelayedPriorityQueue. Cannot be called on an empty DelayedPriorityQueue.
38   scoped_refptr<TaskSource> PeekTaskSource() const;
39 
40   // Removes and returns the highest priority TaskSource in this
41   // DelayedPriorityQueue. Cannot be called on an empty DelayedPriorityQueue.
42   scoped_refptr<TaskSource> PopTaskSource();
43 
44   // Removes |task_source| from the DelayedPriorityQueue. Returns a TaskSource
45   // which evaluates to true if successful, or false if |task_source| is not
46   // currently in the DelayedPriorityQueue or the DelayedPriorityQueue is empty.
47   scoped_refptr<TaskSource> RemoveTaskSource(
48       scoped_refptr<TaskSource> task_source);
49 
50   // Updates the delayed sort key of |task_source| to |delayed_sort_key|,
51   // reordering |task_source| in the queue if necessary. No-ops if the
52   // TaskSource is not in the DelayedPriorityQueue or the DelayedPriorityQueue
53   // is empty.
54   void UpdateDelayedSortKey(scoped_refptr<TaskSource> task_source);
55 
56   // Returns true if the DelayedPriorityQueue is empty.
57   bool IsEmpty() const;
58 
59   // Returns the number of TaskSources in the DelayedPriorityQueue.
60   size_t Size() const;
61 
62   // Set the DelayedPriorityQueue to empty all its TaskSources of Tasks when it
63   // is destroyed; needed to prevent memory leaks caused by a reference cycle
64   // (TaskSource -> Task -> TaskRunner -> TaskSource...) during test teardown.
65   void EnableFlushTaskSourcesOnDestroyForTesting();
66 
67  private:
68   // A class combining a TaskSource and the delayed_sort_key that determines
69   // its position in a PriorityQueue.
70   class TaskSourceAndDelayedSortKey;
71 
72   struct DelayedPriorityQueueComparisonOperator {
73     bool operator()(const TaskSourceAndDelayedSortKey& lhs,
74                     const TaskSourceAndDelayedSortKey& rhs) const;
75   };
76 
77   using ContainerType = IntrusiveHeap<TaskSourceAndDelayedSortKey,
78                                       DelayedPriorityQueueComparisonOperator>;
79 
80   ContainerType container_;
81 
82   // Should only be enabled by EnableFlushTaskSourcesOnDestroyForTesting().
83   bool is_flush_task_sources_on_destroy_enabled_ = false;
84 };
85 
86 }  // namespace base::internal
87 
88 #endif  // BASE_TASK_THREAD_POOL_DELAYED_PRIORITY_QUEUE_H_
89