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/priority_dispatch.h" | |
6 | |
7 #include "base/logging.h" | |
8 | |
9 namespace net { | |
10 | |
11 // We rely on the priority enum values being sequential having starting at 0, | |
12 // and increasing for lower priorities. | |
13 COMPILE_ASSERT(HIGHEST == 0u && | |
14 LOWEST > HIGHEST && | |
15 IDLE > LOWEST && | |
16 NUM_PRIORITIES > IDLE, | |
17 priority_indexes_incompatible); | |
18 | |
19 // static | |
20 PriorityDispatch::Limits PriorityDispatch::Limits::MakeAny( | |
21 size_t max_idle) { | |
22 Limits limits = {{0, 0, 0, 0, max_idle}}; | |
mmenke
2011/12/21 16:22:58
You're relying on NUM_PRIORITIES being 5 here. Th
szym
2011/12/28 01:24:10
Done.
| |
23 return limits; | |
24 } | |
25 | |
26 size_t PriorityDispatch::Limits::Total() const { | |
27 size_t total = 0; | |
28 for (size_t i = 0; i < NUM_PRIORITIES; ++i) { | |
29 total+= reserved_slots[i]; | |
mmenke
2011/12/21 16:22:58
nit: Space before the +=. Applies elsewhere in t
szym
2011/12/28 01:24:10
Done.
| |
30 } | |
31 return total; | |
32 } | |
33 | |
34 PriorityDispatch::PriorityDispatch(const Limits& limits, size_t max_queued) | |
35 : num_running_jobs_(0), max_queued_jobs_(max_queued) { | |
36 size_t total = 0; | |
37 for (size_t i = 0; i < NUM_PRIORITIES; ++i) { | |
38 total+= limits.reserved_slots[NUM_PRIORITIES - i - 1]; | |
39 max_running_jobs_[NUM_PRIORITIES - i - 1] = total; | |
40 } | |
41 } | |
42 | |
43 PriorityDispatch::~PriorityDispatch() {} | |
44 | |
45 void PriorityDispatch::SetMaxQueued(size_t max_queued) { | |
46 DCHECK_EQ(0u, num_queued_jobs()); | |
47 max_queued_jobs_ = max_queued; | |
48 } | |
49 | |
50 PriorityDispatch::Handle PriorityDispatch::Add(Job* job, | |
51 RequestPriority priority) { | |
52 DCHECK(job); | |
53 if (num_running_jobs_ < max_running_jobs_[priority]) { | |
54 ++num_running_jobs_; | |
55 job->Start(); | |
56 return Handle(); | |
57 } | |
58 Handle handle = queue_.Insert(job, priority); | |
59 if (queue_.size() > max_queued_jobs_) { | |
60 // Evict oldest lowest-priority job. | |
61 Handle evicted = queue_.OldestLowest(); | |
62 DCHECK(!evicted.is_null()); | |
63 if (evicted.equals(handle)) | |
64 handle = Handle(); | |
65 Job* evicted_job = evicted.value(); | |
66 queue_.Erase(evicted); | |
67 DCHECK(evicted_job); | |
68 evicted_job->OnEvicted(); | |
69 } | |
70 return handle; | |
71 } | |
72 | |
73 void PriorityDispatch::Cancel(const Handle& handle) { | |
74 queue_.Erase(handle); | |
75 } | |
76 | |
77 PriorityDispatch::Handle PriorityDispatch::Update(const Handle& handle, | |
78 RequestPriority priority) { | |
79 DCHECK(!handle.is_null()); | |
80 DCHECK_GE(num_running_jobs_, max_running_jobs_[handle.priority()]) << | |
81 "Job should not be in queue when limits permit it to start."; | |
82 if (num_running_jobs_ < max_running_jobs_[priority]) { | |
mmenke
2011/12/21 16:22:58
You're pretty much duplicating half of OnJobFinish
szym
2011/12/28 01:24:10
Done.
| |
83 Job* job = handle.value(); | |
84 queue_.Erase(handle); | |
85 ++num_running_jobs_; | |
86 DCHECK(job); | |
87 job->Start(); | |
88 return Handle(); | |
89 } | |
90 return queue_.Move(handle, priority); | |
mmenke
2011/12/21 16:22:58
I think it might be a little simpler, and not all
szym
2011/12/28 01:24:10
Agreed. "Move" would make more sense if it preserv
| |
91 } | |
92 | |
93 void PriorityDispatch::OnJobFinished() { | |
94 DCHECK_GT(num_running_jobs_, 0u); | |
95 --num_running_jobs_; | |
96 Handle handle = queue_.First(); | |
97 if (handle.is_null()) { | |
98 DCHECK_EQ(0u, queue_.size()); | |
99 return; | |
100 } | |
101 if (num_running_jobs_ < max_running_jobs_[handle.priority()]) { | |
102 Job* job = handle.value(); | |
103 queue_.Erase(handle); | |
104 ++num_running_jobs_; | |
105 DCHECK(job); | |
106 job->Start(); | |
107 } | |
108 } | |
109 | |
110 } // namespace net | |
111 | |
112 | |
OLD | NEW |