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

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

Issue 11270027: Add a ResourceScheduler to ResourceDispatcherHost. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Manage ownership with handles Created 8 years, 1 month 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/renderer_host/resource_scheduler.h"
6
7 #include "base/stl_util.h"
8 #include "content/browser/renderer_host/resource_loader.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 ResourceScheduler::ResourceScheduler() {
23 }
24
25 ResourceScheduler::~ResourceScheduler() {
26 }
27
28 ResourceScheduler::LoadHandle* ResourceScheduler::ScheduleLoad(
29 int child_id,
30 int route_id,
31 int request_id,
32 const linked_ptr<ResourceLoader>& loader) {
33 if (route_id == 0) {
34 // <a ping> requests don't have a route_id.
35 loader->StartRequest();
36 return new UnscheduledLoadHandle(loader);
37 }
38
39 ClientId client_id = MakeClientId(child_id, route_id);
40 CHECK(ContainsKey(client_map_, client_id));
41
42 Client* client = client_map_[client_id];
43 DCHECK(!client->closed);
44 ScheduledLoadHandle* handle = new ScheduledLoadHandle(
45 client_id, request_id, loader, this);
46 Request request = { request_id, loader.get() };
47 if (loader->request()->priority() < net::MEDIUM &&
48 !client->in_flight_requests.empty() && !client->has_painted) {
49 client->pending_requests.push_back(request);
50 return handle;
51 }
52
53 StartRequest(request, client);
54 return handle;
55 }
56
57 void ResourceScheduler::RemoveLoad(ClientId client_id, int request_id) {
58 DCHECK(ContainsKey(client_map_, client_id));
59 Client* client = client_map_[client_id];
60 RequestIdSet::iterator it = client->in_flight_requests.find(request_id);
61 if (it == client->in_flight_requests.end()) {
62 bool removed = false;
63 RequestQueue::iterator queue_it;
64 for (queue_it = client->pending_requests.begin();
65 queue_it != client->pending_requests.end(); ++queue_it) {
66 if (queue_it->request_id == request_id) {
67 client->pending_requests.erase(queue_it);
68 removed = true;
69 break;
70 }
71 }
72 DCHECK(removed);
73 DCHECK(!ContainsKey(client->in_flight_requests, request_id));
74 } else {
75 bool erased = client->in_flight_requests.erase(request_id);
76 DCHECK(erased);
77 }
78
79 if (client->closed) {
80 if (client->in_flight_requests.empty()
81 && client->pending_requests.empty()) {
82 delete client;
83 client_map_.erase(client_id);
84 }
85 } else if (client->in_flight_requests.empty()) {
86 LoadPendingRequests(client);
87 }
88 }
89
90 void ResourceScheduler::OnCreate(int child_id, int route_id) {
91 ClientId client_id = MakeClientId(child_id, route_id);
92 DCHECK(!ContainsKey(client_map_, client_id));
93 client_map_[client_id] = new Client;
94 }
95
96 void ResourceScheduler::OnNavigate(int child_id, int route_id) {
97 ClientId client_id = MakeClientId(child_id, route_id);
98 DCHECK(ContainsKey(client_map_, client_id));
99 Client* client = client_map_[client_id];
100 client->has_painted = false;
101 }
102
103 void ResourceScheduler::OnPaint(int child_id, int route_id) {
104 ClientId client_id = MakeClientId(child_id, route_id);
105 DCHECK(ContainsKey(client_map_, client_id));
106 Client* client = client_map_[client_id];
107 if (!client->has_painted) {
108 client->has_painted = true;
109 LoadPendingRequests(client);
110 }
111 }
112
113 void ResourceScheduler::OnDestroy(int child_id, int route_id) {
114 ClientId client_id = MakeClientId(child_id, route_id);
115 DCHECK(ContainsKey(client_map_, client_id));
116 Client* client = client_map_[client_id];
117 if (client->pending_requests.empty() && client->in_flight_requests.empty()) {
118 delete client;
119 client_map_.erase(client_id);
120 } else {
121 client->closed = true;
122 }
123 }
124
125 void ResourceScheduler::StartRequest(Request request, Client* client) {
126 client->in_flight_requests.insert(request.request_id);
127 request.loader->StartRequest();
128 }
129
130 void ResourceScheduler::LoadPendingRequests(Client* client) {
131 RequestQueue::iterator it;
132 for (it = client->pending_requests.begin();
133 it != client->pending_requests.end(); ++it) {
134 StartRequest(*it, client);
135 }
136 client->pending_requests.clear();
137 }
138
139 ResourceScheduler::ScheduledLoadHandle::ScheduledLoadHandle(
140 ClientId client_id,
141 int request_id,
142 const linked_ptr<ResourceLoader>& loader,
143 ResourceScheduler* scheduler)
144 : client_id_(client_id),
145 request_id_(request_id),
146 loader_(loader),
147 scheduler_(scheduler) {
148 }
149
150 ResourceScheduler::ScheduledLoadHandle::~ScheduledLoadHandle() {
151 scheduler_->RemoveLoad(client_id_, request_id_);
152 }
153
154 ResourceScheduler::UnscheduledLoadHandle::UnscheduledLoadHandle(
155 const linked_ptr<ResourceLoader>& loader)
156 : loader_(loader) {
157 }
158
159 ResourceScheduler::UnscheduledLoadHandle::~UnscheduledLoadHandle() {
160 }
161
162 ResourceScheduler::Client::Client()
163 : has_painted(false),
164 closed(false) {
165 }
166
167 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698