xref: /aosp_15_r20/external/cronet/net/base/prioritized_task_runner.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #include "net/base/prioritized_task_runner.h"
6 
7 #include <algorithm>
8 
9 #include "base/functional/bind.h"
10 #include "base/task/task_runner.h"
11 #include "base/task/thread_pool.h"
12 
13 namespace net {
14 
Job(const base::Location & from_here,base::OnceClosure task,base::OnceClosure reply,uint32_t priority,uint32_t task_count)15 PrioritizedTaskRunner::Job::Job(const base::Location& from_here,
16                                 base::OnceClosure task,
17                                 base::OnceClosure reply,
18                                 uint32_t priority,
19                                 uint32_t task_count)
20     : from_here(from_here),
21       task(std::move(task)),
22       reply(std::move(reply)),
23       priority(priority),
24       task_count(task_count) {}
25 
26 PrioritizedTaskRunner::Job::Job() = default;
27 
28 PrioritizedTaskRunner::Job::~Job() = default;
29 PrioritizedTaskRunner::Job::Job(Job&& other) = default;
30 PrioritizedTaskRunner::Job& PrioritizedTaskRunner::Job::operator=(Job&& other) =
31     default;
32 
PrioritizedTaskRunner(const base::TaskTraits & task_traits)33 PrioritizedTaskRunner::PrioritizedTaskRunner(
34     const base::TaskTraits& task_traits)
35     : task_traits_(task_traits) {}
36 
PostTaskAndReply(const base::Location & from_here,base::OnceClosure task,base::OnceClosure reply,uint32_t priority)37 void PrioritizedTaskRunner::PostTaskAndReply(const base::Location& from_here,
38                                              base::OnceClosure task,
39                                              base::OnceClosure reply,
40                                              uint32_t priority) {
41   Job job(from_here, std::move(task), std::move(reply), priority,
42           task_count_++);
43   task_jobs_.Push(std::move(job));
44 
45   scoped_refptr<base::TaskRunner> task_runner;
46   if (task_runner_for_testing_) {
47     task_runner = task_runner_for_testing_;
48   } else {
49     task_runner = base::ThreadPool::CreateSequencedTaskRunner(task_traits_);
50   }
51 
52   task_runner->PostTaskAndReply(
53       from_here,
54       base::BindOnce(&PrioritizedTaskRunner::RunTaskAndPostReply, this),
55       base::BindOnce(&PrioritizedTaskRunner::RunReply, this));
56 }
57 
58 PrioritizedTaskRunner::~PrioritizedTaskRunner() = default;
59 
RunTaskAndPostReply()60 void PrioritizedTaskRunner::RunTaskAndPostReply() {
61   // Find the next job to run.
62   Job job = task_jobs_.Pop();
63 
64   std::move(job.task).Run();
65 
66   // Add the job to the reply priority queue.
67   reply_jobs_.Push(std::move(job));
68 }
69 
RunReply()70 void PrioritizedTaskRunner::RunReply() {
71   // Find the next job to run.
72   Job job = reply_jobs_.Pop();
73 
74   // Run the job.
75   std::move(job.reply).Run();
76 }
77 
78 struct PrioritizedTaskRunner::JobComparer {
operator ()net::PrioritizedTaskRunner::JobComparer79   bool operator()(const Job& left, const Job& right) {
80     if (left.priority == right.priority) {
81       return left.task_count > right.task_count;
82     }
83     return left.priority > right.priority;
84   }
85 };
86 
87 PrioritizedTaskRunner::JobPriorityQueue::JobPriorityQueue() = default;
88 PrioritizedTaskRunner::JobPriorityQueue::~JobPriorityQueue() = default;
89 
Push(Job job)90 void PrioritizedTaskRunner::JobPriorityQueue::Push(Job job) {
91   base::AutoLock auto_lock(lock_);
92   heap_.push_back(std::move(job));
93   std::push_heap(heap_.begin(), heap_.end(), JobComparer());
94 }
95 
Pop()96 PrioritizedTaskRunner::Job PrioritizedTaskRunner::JobPriorityQueue::Pop() {
97   base::AutoLock auto_lock(lock_);
98   CHECK(!heap_.empty());
99   std::pop_heap(heap_.begin(), heap_.end(), JobComparer());
100   Job job = std::move(heap_.back());
101   heap_.pop_back();
102   return job;
103 }
104 
105 }  // namespace net
106