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

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

Powered by Google App Engine
This is Rietveld 408576698