OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
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_dispatcher.h" | |
6 | |
7 #include "base/logging.h" | |
8 | |
9 namespace net { | |
10 | |
11 PrioritizedDispatcher::PrioritizedDispatcher(size_t num_priorities, | |
12 const Limits& limits) | |
13 : queue_(num_priorities), | |
14 max_running_jobs_(num_priorities), | |
15 num_running_jobs_(0) { | |
16 // No reserved slots beyond num_priorities are allowed. | |
17 for (size_t i = num_priorities; i < limits.reserved_slots.size(); ++i) { | |
cbentzel
2012/01/05 18:32:20
Why aren't reserved_slots.size() and num_prioritie
szym
2012/01/05 19:00:29
This would require callers of HostResolverImpl() t
| |
18 DCHECK_EQ(0u, limits.reserved_slots[i]); | |
19 } | |
20 size_t total = 0; | |
21 for (size_t i = std::min(num_priorities, limits.reserved_slots.size()); | |
22 i > 0; --i) { | |
23 total += limits.reserved_slots[i - 1]; | |
24 max_running_jobs_[i - 1] = total; | |
25 } | |
26 // Unreserved slots are available for all priorities. | |
27 DCHECK_LE(total, limits.total_jobs) << "sum(reserved_slots) <= total_jobs"; | |
28 size_t spare = limits.total_jobs - total; | |
29 for (size_t i = 0; i < num_priorities; ++i) { | |
30 max_running_jobs_[i] += spare; | |
31 } | |
32 } | |
33 | |
34 PrioritizedDispatcher::~PrioritizedDispatcher() {} | |
35 | |
36 PrioritizedDispatcher::Handle PrioritizedDispatcher::Add( | |
37 Job* job, size_t priority) { | |
38 DCHECK(job); | |
39 DCHECK_LT(priority, num_priorities()); | |
40 if (num_running_jobs_ < max_running_jobs_[priority]) { | |
41 ++num_running_jobs_; | |
42 job->Start(); | |
cbentzel
2012/01/05 18:32:20
It looks like there are no re-entrancy problems if
szym
2012/01/05 19:00:29
Already mentioned.
| |
43 return Handle(); | |
44 } | |
45 return queue_.Insert(job, priority); | |
46 } | |
47 | |
48 void PrioritizedDispatcher::Cancel(const Handle& handle) { | |
49 queue_.Erase(handle); | |
50 } | |
51 | |
52 PrioritizedDispatcher::Job* PrioritizedDispatcher::EvictOldestLowest() { | |
53 Handle handle = queue_.FirstMax(); | |
54 if (handle.is_null()) | |
55 return NULL; | |
56 Job* job = handle.value(); | |
57 Cancel(handle); | |
58 return job; | |
59 } | |
60 | |
61 PrioritizedDispatcher::Handle PrioritizedDispatcher::Update( | |
62 const Handle& handle, size_t priority) { | |
63 DCHECK(!handle.is_null()); | |
64 DCHECK_LT(priority, num_priorities()); | |
65 DCHECK_GE(num_running_jobs_, max_running_jobs_[handle.priority()]) << | |
66 "Job should not be in queue when limits permit it to start."; | |
67 DCHECK_LE(queue_.size(), max_queued_jobs_); | |
68 | |
69 if (handle.priority() == priority) | |
70 return handle; | |
71 | |
72 if (DispatchJob(handle, priority)) | |
73 return Handle(); | |
74 Job* job = handle.value(); | |
75 queue_.Erase(handle); | |
76 return queue_.Insert(job, priority); | |
77 } | |
78 | |
79 void PrioritizedDispatcher::OnJobFinished() { | |
80 DCHECK_GT(num_running_jobs_, 0u); | |
81 --num_running_jobs_; | |
82 Handle handle = queue_.FirstMin(); | |
83 if (handle.is_null()) { | |
84 DCHECK_EQ(0u, queue_.size()); | |
85 return; | |
86 } | |
87 DispatchJob(handle, handle.priority()); | |
88 } | |
89 | |
90 bool PrioritizedDispatcher::DispatchJob(const Handle& handle, | |
91 size_t job_priority) { | |
92 DCHECK_LT(job_priority, num_priorities()); | |
93 if (num_running_jobs_ >= max_running_jobs_[job_priority]) | |
94 return false; | |
95 Job* job = handle.value(); | |
96 queue_.Erase(handle); | |
97 ++num_running_jobs_; | |
98 DCHECK(job); | |
cbentzel
2012/01/05 18:32:20
This DCHECK isn't needed - you check it at Add tim
| |
99 job->Start(); | |
100 return true; | |
101 } | |
102 | |
103 } // namespace net | |
104 | |
105 | |
OLD | NEW |