Chromium Code Reviews| Index: content/browser/loader/resource_scheduler.cc |
| diff --git a/content/browser/loader/resource_scheduler.cc b/content/browser/loader/resource_scheduler.cc |
| index 85adbdb30e275631b53af88286e75b658e73a16c..e3f17c41c6e8d0cb31d2dd09a96848060498c6b7 100644 |
| --- a/content/browser/loader/resource_scheduler.cc |
| +++ b/content/browser/loader/resource_scheduler.cc |
| @@ -125,6 +125,7 @@ class ResourceScheduler::ScheduledResourceRequest |
| request_(request), |
| ready_(false), |
| deferred_(false), |
| + critical_(false), |
| scheduler_(scheduler), |
| priority_(priority), |
| fifo_ordering_(0), |
| @@ -165,6 +166,12 @@ class ResourceScheduler::ScheduledResourceRequest |
| void set_accounted_as_delayable_request(bool accounted) { |
| accounted_as_delayable_request_ = accounted; |
| } |
| + bool critical() const { |
| + return critical_; |
| + } |
| + void set_critical(bool critical) { |
| + critical_ = critical; |
| + } |
| private: |
| // ResourceMessageDelegate interface: |
| @@ -195,6 +202,7 @@ class ResourceScheduler::ScheduledResourceRequest |
| net::URLRequest* request_; |
| bool ready_; |
| bool deferred_; |
| + bool critical_; |
| ResourceScheduler* scheduler_; |
| RequestPriorityParams priority_; |
| uint32 fifo_ordering_; |
| @@ -238,6 +246,7 @@ class ResourceScheduler::Client { |
| has_body_(false), |
| using_spdy_proxy_(false), |
| total_delayable_count_(0), |
| + total_critical_count_(0), |
| throttle_state_(ResourceScheduler::THROTTLED) { |
| scheduler_ = scheduler; |
| } |
| @@ -279,6 +288,7 @@ class ResourceScheduler::Client { |
| it != in_flight_requests_.end(); ++it) { |
| unowned_requests.insert(*it); |
| (*it)->set_accounted_as_delayable_request(false); |
| + (*it)->set_critical(false); |
| } |
| ClearInFlightRequests(); |
| return unowned_requests; |
| @@ -375,6 +385,7 @@ class ResourceScheduler::Client { |
| // The priority and SPDY support may have changed, so update the |
| // delayable count. |
| SetRequestDelayable(request, IsDelayableRequest(request)); |
| + SetRequestCritical(request, IsCriticalRequest(request)); |
|
mmenke
2014/08/12 17:18:37
Should we have an enum instead of bools?
Pat Meenan
2014/08/13 00:20:12
Done.
|
| // Request has already started. |
| return; |
| } |
| @@ -443,6 +454,8 @@ class ResourceScheduler::Client { |
| in_flight_requests_.insert(request); |
| if (IsDelayableRequest(request)) |
| SetRequestDelayable(request, true); |
| + if (IsCriticalRequest(request)) |
| + SetRequestCritical(request, true); |
| } |
| void EraseInFlightRequest(ScheduledResourceRequest* request) { |
| @@ -450,11 +463,14 @@ class ResourceScheduler::Client { |
| DCHECK_EQ(1u, erased); |
| SetRequestDelayable(request, false); |
| DCHECK_LE(total_delayable_count_, in_flight_requests_.size()); |
| + SetRequestCritical(request, false); |
| + DCHECK_LE(total_critical_count_, in_flight_requests_.size()); |
| } |
| void ClearInFlightRequests() { |
| in_flight_requests_.clear(); |
| total_delayable_count_ = 0; |
| + total_critical_count_ = 0; |
| } |
| bool IsDelayableRequest(ScheduledResourceRequest* request) { |
| @@ -481,6 +497,23 @@ class ResourceScheduler::Client { |
| request->set_accounted_as_delayable_request(delayable); |
| } |
| + bool IsCriticalRequest(ScheduledResourceRequest* request) { |
| + if (!has_body_ && request->url_request()->priority() >= net::LOW) |
| + return true; |
| + return false; |
| + } |
| + |
| + void SetRequestCritical(ScheduledResourceRequest* request, |
| + bool critical) { |
| + if (request->critical() == critical) |
| + return; |
| + if (critical) |
| + total_critical_count_++; |
| + else |
| + total_critical_count_--; |
| + request->set_critical(critical); |
| + } |
| + |
| bool ShouldKeepSearching( |
| const net::HostPortPair& active_request_host) const { |
| size_t same_host_count = 0; |
| @@ -504,7 +537,7 @@ class ResourceScheduler::Client { |
| // ShouldStartRequest is the main scheduling algorithm. |
| // |
| - // Requests are categorized into three categories: |
| + // Requests are categorized into five categories: |
| // |
| // 1. Non-delayable requests: |
| // * Synchronous requests. |
| @@ -515,20 +548,25 @@ class ResourceScheduler::Client { |
| // 3. High-priority requests: |
| // * Higher priority requests (>= net::LOW). |
| // |
| - // 4. Low priority requests |
| + // 4. Critical requests: |
| + // * High-priority requests initiated before the renderer has a <body>. |
| + // |
| + // 5. Low priority requests |
| // |
| // The following rules are followed: |
| // |
| // ACTIVE_AND_LOADING and UNTHROTTLED Clients follow these rules: |
| // * Non-delayable, High-priority and SDPY capable requests are issued |
| - // immediately |
| + // immediately. |
| // * If no high priority requests are in flight, start loading low priority |
| // requests. |
| // * Low priority requests are delayable. |
| - // * Once the renderer has a <body>, start loading delayable requests. |
| + // * Allow one delayable request toload at a time while critical requests |
| + // are loading. |
| + // * Once all critical requests have finished loading, start loading |
| + // delayable requests. |
| // * Never exceed 10 delayable requests in flight per client. |
| // * Never exceed 6 delayable requests for a given host. |
| - // * Prior to <body>, allow one delayable request to load at a time. |
| // |
| // THROTTLED Clients follow these rules: |
| // * Non-delayable and SPDY-capable requests are issued immediately. |
| @@ -602,7 +640,8 @@ class ResourceScheduler::Client { |
| bool have_immediate_requests_in_flight = |
| in_flight_requests_.size() > num_delayable_requests_in_flight; |
| - if (have_immediate_requests_in_flight && !has_body_ && |
| + if (have_immediate_requests_in_flight && |
| + total_critical_count_ != 0 && |
| num_delayable_requests_in_flight != 0) { |
| return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
| } |
| @@ -658,6 +697,8 @@ class ResourceScheduler::Client { |
| ResourceScheduler* scheduler_; |
| // The number of delayable in-flight requests. |
| size_t total_delayable_count_; |
| + // The number of critical in-flight requests. |
| + size_t total_critical_count_; |
| ResourceScheduler::ClientThrottleState throttle_state_; |
| }; |