| 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 |