Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(812)

Side by Side Diff: content/browser/loader/resource_scheduler.cc

Issue 11270027: Add a ResourceScheduler to ResourceDispatcherHost. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix typo Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "content/browser/loader/resource_scheduler.h"
6
7 #include "base/stl_util.h"
8 #include "net/base/load_flags.h"
9 #include "net/base/request_priority.h"
10 #include "net/url_request/url_request.h"
11
12 namespace content {
13
14 namespace {
15
16 ResourceScheduler::ClientId MakeClientId(int child_id, int route_id) {
17 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id;
18 }
19
20 } // unnamed namespace
21
22 class LoadHandleImpl : public ResourceScheduler::LoadHandle {
23 public:
24 LoadHandleImpl(ResourceScheduler::SchedulerId scheduler_id,
25 ResourceScheduler::ClientId client_id,
26 ResourceScheduler* scheduler)
27 : scheduler_id_(scheduler_id),
28 client_id_(client_id),
29 scheduler_(scheduler) {
30 }
31
32 virtual ~LoadHandleImpl() {
33 scheduler_->RemoveLoad(scheduler_id_, client_id_);
34 }
35
36 private:
37 ResourceScheduler::SchedulerId scheduler_id_;
38 ResourceScheduler::ClientId client_id_;
39 ResourceScheduler* scheduler_;
40 };
willchan no longer on Chromium 2012/12/13 06:30:43 DISALLOW_COPY_AND_ASSIGN
James Simonsen 2012/12/14 20:23:23 Done.
41
42 ResourceScheduler::ResourceScheduler()
43 : next_scheduler_id_(0) {
44 }
45
46 ResourceScheduler::~ResourceScheduler() {
47 }
48
49 scoped_ptr<ResourceScheduler::LoadHandle> ResourceScheduler::ScheduleLoad(
50 int child_id,
51 int route_id,
52 Loadable* loadable) {
53 SchedulerId scheduler_id = ++next_scheduler_id_;
54 ClientId client_id = MakeClientId(child_id, route_id);
55 scoped_ptr<LoadHandle> handle(new LoadHandleImpl(
56 scheduler_id, client_id, this));
57
58 if (route_id == 0 || !ContainsKey(client_map_, client_id)) {
59 // <a ping> requests don't belong to a specific page. Most tests don't call
60 // OnCreate et. al. as needed to register Clients either.
61 unowned_requests_.insert(scheduler_id);
62 loadable->StartRequest();
63 return handle.Pass();
64 }
65
66 Client* client = client_map_[client_id];
67 DCHECK(!client->has_closed);
68 Request request = { scheduler_id, loadable };
69
70 // Treat synchronous requests as high priority.
71 bool is_low_priority = loadable->url_request()->priority() < net::MEDIUM &&
72 !(loadable->url_request()->load_flags() & net::LOAD_IGNORE_LIMITS);
73
74 if (is_low_priority && !client->in_flight_requests.empty() &&
75 !client->has_painted) {
76 client->pending_requests.push_back(request);
77 } else {
78 StartRequest(request, client);
79 }
80 return handle.Pass();
81 }
82
83 void ResourceScheduler::RemoveLoad(SchedulerId scheduler_id,
84 ClientId client_id) {
85 if (ContainsKey(unowned_requests_, scheduler_id)) {
86 unowned_requests_.erase(scheduler_id);
87 return;
88 }
89
90 DCHECK(ContainsKey(client_map_, client_id));
91 Client* client = client_map_[client_id];
92 SchedulerIdSet::iterator it = client->in_flight_requests.find(scheduler_id);
93 if (it == client->in_flight_requests.end()) {
94 bool removed = false;
95 RequestQueue::iterator queue_it;
96 for (queue_it = client->pending_requests.begin();
97 queue_it != client->pending_requests.end(); ++queue_it) {
98 if (queue_it->scheduler_id == scheduler_id) {
99 client->pending_requests.erase(queue_it);
100 removed = true;
101 break;
102 }
103 }
104 DCHECK(removed);
105 DCHECK(!ContainsKey(client->in_flight_requests, scheduler_id));
106 } else {
107 size_t erased = client->in_flight_requests.erase(scheduler_id);
108 DCHECK(erased);
109 }
110
111 if (client->has_closed) {
112 if (client->in_flight_requests.empty()
113 && client->pending_requests.empty()) {
114 delete client;
115 client_map_.erase(client_id);
116 }
117 } else if (client->in_flight_requests.empty()) {
118 LoadPendingRequests(client);
119 }
120 }
121
122 void ResourceScheduler::OnCreate(int child_id, int route_id) {
123 ClientId client_id = MakeClientId(child_id, route_id);
124 DCHECK(!ContainsKey(client_map_, client_id));
125 client_map_[client_id] = new Client;
126 }
127
128 void ResourceScheduler::OnNavigate(int child_id, int route_id) {
129 ClientId client_id = MakeClientId(child_id, route_id);
130 if (!ContainsKey(client_map_, client_id)) {
131 return;
132 }
133
134 Client* client = client_map_[client_id];
135 client->has_painted = false;
136 }
137
138 void ResourceScheduler::OnPaint(int child_id, int route_id) {
139 ClientId client_id = MakeClientId(child_id, route_id);
140 if (!ContainsKey(client_map_, client_id)) {
141 return;
142 }
143
144 Client* client = client_map_[client_id];
145 if (!client->has_painted) {
146 client->has_painted = true;
147 LoadPendingRequests(client);
148 }
149 }
150
151 void ResourceScheduler::OnDestroy(int child_id, int route_id) {
152 ClientId client_id = MakeClientId(child_id, route_id);
153 if (!ContainsKey(client_map_, client_id)) {
154 return;
155 }
156
157 Client* client = client_map_[client_id];
158 if (client->pending_requests.empty() && client->in_flight_requests.empty()) {
159 delete client;
160 client_map_.erase(client_id);
161 } else {
162 client->has_closed = true;
163 }
164 }
165
166 void ResourceScheduler::StartRequest(Request request, Client* client) {
167 client->in_flight_requests.insert(request.scheduler_id);
168 request.loadable->StartRequest();
169 }
170
171 void ResourceScheduler::LoadPendingRequests(Client* client) {
172 RequestQueue::iterator it;
173 for (it = client->pending_requests.begin();
174 it != client->pending_requests.end(); ++it) {
175 StartRequest(*it, client);
176 }
177 client->pending_requests.clear();
178 }
179
180 ResourceScheduler::Client::Client()
181 : has_painted(false),
182 has_closed(false) {
183 }
184
185 ResourceScheduler::Client::~Client() {
186 }
187
188 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698