OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <set> | 5 #include <set> |
6 | 6 |
7 #include "content/browser/loader/resource_scheduler.h" | 7 #include "content/browser/loader/resource_scheduler.h" |
8 | 8 |
9 #include "base/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 ScheduledResourceRequest(const ClientId& client_id, | 160 ScheduledResourceRequest(const ClientId& client_id, |
161 net::URLRequest* request, | 161 net::URLRequest* request, |
162 ResourceScheduler* scheduler, | 162 ResourceScheduler* scheduler, |
163 const RequestPriorityParams& priority) | 163 const RequestPriorityParams& priority) |
164 : ResourceMessageDelegate(request), | 164 : ResourceMessageDelegate(request), |
165 client_id_(client_id), | 165 client_id_(client_id), |
166 client_state_on_creation_(scheduler->GetClientState(client_id_)), | 166 client_state_on_creation_(scheduler->GetClientState(client_id_)), |
167 request_(request), | 167 request_(request), |
168 ready_(false), | 168 ready_(false), |
169 deferred_(false), | 169 deferred_(false), |
| 170 is_async_revalidation_(false), |
170 classification_(NORMAL_REQUEST), | 171 classification_(NORMAL_REQUEST), |
171 scheduler_(scheduler), | 172 scheduler_(scheduler), |
172 priority_(priority), | 173 priority_(priority), |
173 fifo_ordering_(0) { | 174 fifo_ordering_(0) { |
| 175 is_async_revalidation_ = |
| 176 ResourceRequestInfo::ForRequest(request)->IsAsyncRevalidation(); |
174 } | 177 } |
175 | 178 |
176 ~ScheduledResourceRequest() override { scheduler_->RemoveRequest(this); } | 179 ~ScheduledResourceRequest() override { scheduler_->RemoveRequest(this); } |
177 | 180 |
178 void Start() { | 181 void Start() { |
179 ready_ = true; | 182 ready_ = true; |
180 if (!request_->status().is_success()) | 183 if (!request_->status().is_success()) |
181 return; | 184 return; |
182 base::TimeTicks time = base::TimeTicks::Now(); | 185 base::TimeTicks time = base::TimeTicks::Now(); |
183 ClientState current_state = scheduler_->GetClientState(client_id_); | 186 ClientState current_state = scheduler_->GetClientState(client_id_); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 uint32 fifo_ordering() const { return fifo_ordering_; } | 222 uint32 fifo_ordering() const { return fifo_ordering_; } |
220 void set_fifo_ordering(uint32 fifo_ordering) { | 223 void set_fifo_ordering(uint32 fifo_ordering) { |
221 fifo_ordering_ = fifo_ordering; | 224 fifo_ordering_ = fifo_ordering; |
222 } | 225 } |
223 RequestClassification classification() const { | 226 RequestClassification classification() const { |
224 return classification_; | 227 return classification_; |
225 } | 228 } |
226 void set_classification(RequestClassification classification) { | 229 void set_classification(RequestClassification classification) { |
227 classification_ = classification; | 230 classification_ = classification; |
228 } | 231 } |
| 232 bool is_async_revalidation() const { return is_async_revalidation_; } |
229 | 233 |
230 private: | 234 private: |
231 // ResourceMessageDelegate interface: | 235 // ResourceMessageDelegate interface: |
232 bool OnMessageReceived(const IPC::Message& message) override { | 236 bool OnMessageReceived(const IPC::Message& message) override { |
233 bool handled = true; | 237 bool handled = true; |
234 IPC_BEGIN_MESSAGE_MAP(ScheduledResourceRequest, message) | 238 IPC_BEGIN_MESSAGE_MAP(ScheduledResourceRequest, message) |
235 IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, DidChangePriority) | 239 IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, DidChangePriority) |
236 IPC_MESSAGE_UNHANDLED(handled = false) | 240 IPC_MESSAGE_UNHANDLED(handled = false) |
237 IPC_END_MESSAGE_MAP() | 241 IPC_END_MESSAGE_MAP() |
238 return handled; | 242 return handled; |
(...skipping 10 matching lines...) Expand all Loading... |
249 void DidChangePriority(int request_id, net::RequestPriority new_priority, | 253 void DidChangePriority(int request_id, net::RequestPriority new_priority, |
250 int intra_priority_value) { | 254 int intra_priority_value) { |
251 scheduler_->ReprioritizeRequest(this, new_priority, intra_priority_value); | 255 scheduler_->ReprioritizeRequest(this, new_priority, intra_priority_value); |
252 } | 256 } |
253 | 257 |
254 const ClientId client_id_; | 258 const ClientId client_id_; |
255 const ResourceScheduler::ClientState client_state_on_creation_; | 259 const ResourceScheduler::ClientState client_state_on_creation_; |
256 net::URLRequest* request_; | 260 net::URLRequest* request_; |
257 bool ready_; | 261 bool ready_; |
258 bool deferred_; | 262 bool deferred_; |
| 263 bool is_async_revalidation_; |
259 RequestClassification classification_; | 264 RequestClassification classification_; |
260 ResourceScheduler* scheduler_; | 265 ResourceScheduler* scheduler_; |
261 RequestPriorityParams priority_; | 266 RequestPriorityParams priority_; |
262 uint32 fifo_ordering_; | 267 uint32 fifo_ordering_; |
263 base::TimeTicks time_deferred_; | 268 base::TimeTicks time_deferred_; |
264 | 269 |
265 DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest); | 270 DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest); |
266 }; | 271 }; |
267 | 272 |
268 bool ResourceScheduler::ScheduledResourceSorter::operator()( | 273 bool ResourceScheduler::ScheduledResourceSorter::operator()( |
269 const ScheduledResourceRequest* a, | 274 const ScheduledResourceRequest* a, |
270 const ScheduledResourceRequest* b) const { | 275 const ScheduledResourceRequest* b) const { |
| 276 // Want all other requests to be ordered before async revalidations. |
| 277 if (a->is_async_revalidation() != b->is_async_revalidation()) |
| 278 return b->is_async_revalidation(); |
| 279 |
271 // Want the set to be ordered first by decreasing priority, then by | 280 // Want the set to be ordered first by decreasing priority, then by |
272 // decreasing intra_priority. | 281 // decreasing intra_priority. |
273 // ie. with (priority, intra_priority) | 282 // ie. with (priority, intra_priority) |
274 // [(1, 0), (1, 0), (0, 100), (0, 0)] | 283 // [(1, 0), (1, 0), (0, 100), (0, 0)] |
275 if (a->get_request_priority_params() != b->get_request_priority_params()) | 284 if (a->get_request_priority_params() != b->get_request_priority_params()) |
276 return a->get_request_priority_params().GreaterThan( | 285 return a->get_request_priority_params().GreaterThan( |
277 b->get_request_priority_params()); | 286 b->get_request_priority_params()); |
278 | 287 |
279 // If priority/intra_priority is the same, fall back to fifo ordering. | 288 // If priority/intra_priority is the same, fall back to fifo ordering. |
280 // std::multiset doesn't guarantee this until c++11. | 289 // std::multiset doesn't guarantee this until c++11. |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 // THROTTLED Client | 691 // THROTTLED Client |
683 // * If no high priority requests are in flight, start loading low priority | 692 // * If no high priority requests are in flight, start loading low priority |
684 // requests. | 693 // requests. |
685 // | 694 // |
686 // COALESCED Clients never load requests, with the following exceptions: | 695 // COALESCED Clients never load requests, with the following exceptions: |
687 // * Non-delayable requests are issued imediately. | 696 // * Non-delayable requests are issued imediately. |
688 // * On a (currently 5 second) heart beat, they load all requests as an | 697 // * On a (currently 5 second) heart beat, they load all requests as an |
689 // UNTHROTTLED Client, and then return to the COALESCED state. | 698 // UNTHROTTLED Client, and then return to the COALESCED state. |
690 // * When an active Client makes a request, they are THROTTLED until the | 699 // * When an active Client makes a request, they are THROTTLED until the |
691 // active Client finishes loading. | 700 // active Client finishes loading. |
| 701 // |
| 702 // 6. Async revalidations |
| 703 // * Async revalidations come after all other requests, and are never loaded |
| 704 // until the document has a body. |
692 ShouldStartReqResult ShouldStartRequest( | 705 ShouldStartReqResult ShouldStartRequest( |
693 ScheduledResourceRequest* request) const { | 706 ScheduledResourceRequest* request) const { |
694 const net::URLRequest& url_request = *request->url_request(); | 707 const net::URLRequest& url_request = *request->url_request(); |
695 // Syncronous requests could block the entire render, which could impact | 708 // Syncronous requests could block the entire render, which could impact |
696 // user-observable Clients. | 709 // user-observable Clients. |
697 if (!ResourceRequestInfo::ForRequest(&url_request)->IsAsync()) { | 710 if (!ResourceRequestInfo::ForRequest(&url_request)->IsAsync()) { |
698 return START_REQUEST; | 711 return START_REQUEST; |
699 } | 712 } |
700 | 713 |
701 // TODO(simonjam): This may end up causing disk contention. We should | 714 // TODO(simonjam): This may end up causing disk contention. We should |
702 // experiment with throttling if that happens. | 715 // experiment with throttling if that happens. |
703 // TODO(aiolos): We probably want to Coalesce these as well to avoid | 716 // TODO(aiolos): We probably want to Coalesce these as well to avoid |
704 // waking the disk. | 717 // waking the disk. |
705 if (!url_request.url().SchemeIsHTTPOrHTTPS()) { | 718 if (!url_request.url().SchemeIsHTTPOrHTTPS()) { |
706 return START_REQUEST; | 719 return START_REQUEST; |
707 } | 720 } |
708 | 721 |
| 722 if (request->is_async_revalidation() && !has_body_) { |
| 723 // Because async revalidations are sorted last, all following requests |
| 724 // will also be async revalidations. |
| 725 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
| 726 } |
| 727 |
709 if (throttle_state_ == COALESCED) { | 728 if (throttle_state_ == COALESCED) { |
710 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; | 729 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
711 } | 730 } |
712 | 731 |
713 if (using_spdy_proxy_ && url_request.url().SchemeIs(url::kHttpScheme)) { | 732 if (using_spdy_proxy_ && url_request.url().SchemeIs(url::kHttpScheme)) { |
714 return START_REQUEST; | 733 return START_REQUEST; |
715 } | 734 } |
716 | 735 |
717 net::HostPortPair host_port_pair = | 736 net::HostPortPair host_port_pair = |
718 net::HostPortPair::FromURL(url_request.url()); | 737 net::HostPortPair::FromURL(url_request.url()); |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 client->ReprioritizeRequest( | 1167 client->ReprioritizeRequest( |
1149 request, old_priority_params, new_priority_params); | 1168 request, old_priority_params, new_priority_params); |
1150 } | 1169 } |
1151 | 1170 |
1152 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( | 1171 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( |
1153 int child_id, int route_id) { | 1172 int child_id, int route_id) { |
1154 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; | 1173 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; |
1155 } | 1174 } |
1156 | 1175 |
1157 } // namespace content | 1176 } // namespace content |
OLD | NEW |