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

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

Issue 462813002: Changed resource scheduler to block until all critical resources actually load. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleaned up the request classification tracking logic Created 6 years, 4 months 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
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/stl_util.h" 9 #include "base/stl_util.h"
10 #include "content/common/resource_messages.h" 10 #include "content/common/resource_messages.h"
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 ResourceScheduler* scheduler, 121 ResourceScheduler* scheduler,
122 const RequestPriorityParams& priority) 122 const RequestPriorityParams& priority)
123 : ResourceMessageDelegate(request), 123 : ResourceMessageDelegate(request),
124 client_id_(client_id), 124 client_id_(client_id),
125 request_(request), 125 request_(request),
126 ready_(false), 126 ready_(false),
127 deferred_(false), 127 deferred_(false),
128 scheduler_(scheduler), 128 scheduler_(scheduler),
129 priority_(priority), 129 priority_(priority),
130 fifo_ordering_(0), 130 fifo_ordering_(0),
131 accounted_as_delayable_request_(false) { 131 classification_(NORMAL_REQUEST) {
132 TRACE_EVENT_ASYNC_BEGIN1("net", "URLRequest", request_, 132 TRACE_EVENT_ASYNC_BEGIN1("net", "URLRequest", request_,
133 "url", request->url().spec()); 133 "url", request->url().spec());
134 } 134 }
135 135
136 virtual ~ScheduledResourceRequest() { 136 virtual ~ScheduledResourceRequest() {
137 scheduler_->RemoveRequest(this); 137 scheduler_->RemoveRequest(this);
138 } 138 }
139 139
140 void Start() { 140 void Start() {
141 TRACE_EVENT_ASYNC_STEP_PAST0("net", "URLRequest", request_, "Queued"); 141 TRACE_EVENT_ASYNC_STEP_PAST0("net", "URLRequest", request_, "Queued");
(...skipping 10 matching lines...) Expand all
152 const RequestPriorityParams& get_request_priority_params() const { 152 const RequestPriorityParams& get_request_priority_params() const {
153 return priority_; 153 return priority_;
154 } 154 }
155 const ClientId& client_id() const { return client_id_; } 155 const ClientId& client_id() const { return client_id_; }
156 net::URLRequest* url_request() { return request_; } 156 net::URLRequest* url_request() { return request_; }
157 const net::URLRequest* url_request() const { return request_; } 157 const net::URLRequest* url_request() const { return request_; }
158 uint32 fifo_ordering() const { return fifo_ordering_; } 158 uint32 fifo_ordering() const { return fifo_ordering_; }
159 void set_fifo_ordering(uint32 fifo_ordering) { 159 void set_fifo_ordering(uint32 fifo_ordering) {
160 fifo_ordering_ = fifo_ordering; 160 fifo_ordering_ = fifo_ordering;
161 } 161 }
162 bool accounted_as_delayable_request() const { 162 RequestClassification classification() const {
163 return accounted_as_delayable_request_; 163 return classification_;
164 } 164 }
165 void set_accounted_as_delayable_request(bool accounted) { 165 void set_classification(RequestClassification classification) {
166 accounted_as_delayable_request_ = accounted; 166 classification_ = classification;
167 } 167 }
168 168
169 private: 169 private:
170 // ResourceMessageDelegate interface: 170 // ResourceMessageDelegate interface:
171 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 171 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
172 bool handled = true; 172 bool handled = true;
173 IPC_BEGIN_MESSAGE_MAP(ScheduledResourceRequest, message) 173 IPC_BEGIN_MESSAGE_MAP(ScheduledResourceRequest, message)
174 IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, DidChangePriority) 174 IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, DidChangePriority)
175 IPC_MESSAGE_UNHANDLED(handled = false) 175 IPC_MESSAGE_UNHANDLED(handled = false)
176 IPC_END_MESSAGE_MAP() 176 IPC_END_MESSAGE_MAP()
(...skipping 11 matching lines...) Expand all
188 188
189 void DidChangePriority(int request_id, net::RequestPriority new_priority, 189 void DidChangePriority(int request_id, net::RequestPriority new_priority,
190 int intra_priority_value) { 190 int intra_priority_value) {
191 scheduler_->ReprioritizeRequest(this, new_priority, intra_priority_value); 191 scheduler_->ReprioritizeRequest(this, new_priority, intra_priority_value);
192 } 192 }
193 193
194 ClientId client_id_; 194 ClientId client_id_;
195 net::URLRequest* request_; 195 net::URLRequest* request_;
196 bool ready_; 196 bool ready_;
197 bool deferred_; 197 bool deferred_;
198 RequestClassification classification_;
198 ResourceScheduler* scheduler_; 199 ResourceScheduler* scheduler_;
199 RequestPriorityParams priority_; 200 RequestPriorityParams priority_;
200 uint32 fifo_ordering_; 201 uint32 fifo_ordering_;
201 // True if the request is delayable in |in_flight_requests_|.
202 bool accounted_as_delayable_request_;
203 202
204 DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest); 203 DISALLOW_COPY_AND_ASSIGN(ScheduledResourceRequest);
205 }; 204 };
206 205
207 bool ResourceScheduler::ScheduledResourceSorter::operator()( 206 bool ResourceScheduler::ScheduledResourceSorter::operator()(
208 const ScheduledResourceRequest* a, 207 const ScheduledResourceRequest* a,
209 const ScheduledResourceRequest* b) const { 208 const ScheduledResourceRequest* b) const {
210 // Want the set to be ordered first by decreasing priority, then by 209 // Want the set to be ordered first by decreasing priority, then by
211 // decreasing intra_priority. 210 // decreasing intra_priority.
212 // ie. with (priority, intra_priority) 211 // ie. with (priority, intra_priority)
(...skipping 17 matching lines...) Expand all
230 // Each client represents a tab. 229 // Each client represents a tab.
231 class ResourceScheduler::Client { 230 class ResourceScheduler::Client {
232 public: 231 public:
233 explicit Client(ResourceScheduler* scheduler) 232 explicit Client(ResourceScheduler* scheduler)
234 : is_audible_(false), 233 : is_audible_(false),
235 is_visible_(false), 234 is_visible_(false),
236 is_loaded_(false), 235 is_loaded_(false),
237 is_paused_(false), 236 is_paused_(false),
238 has_body_(false), 237 has_body_(false),
239 using_spdy_proxy_(false), 238 using_spdy_proxy_(false),
240 total_delayable_count_(0), 239 in_flight_delayable_count_(0),
240 total_layout_blocking_count_(0),
241 throttle_state_(ResourceScheduler::THROTTLED) { 241 throttle_state_(ResourceScheduler::THROTTLED) {
242 scheduler_ = scheduler; 242 scheduler_ = scheduler;
243 } 243 }
244 244
245 ~Client() { 245 ~Client() {
246 // Update to default state and pause to ensure the scheduler has a 246 // Update to default state and pause to ensure the scheduler has a
247 // correct count of relevant types of clients. 247 // correct count of relevant types of clients.
248 is_visible_ = false; 248 is_visible_ = false;
249 is_audible_ = false; 249 is_audible_ = false;
250 is_paused_ = true; 250 is_paused_ = true;
251 UpdateThrottleState(); 251 UpdateThrottleState();
252 } 252 }
253 253
254 void ScheduleRequest( 254 void ScheduleRequest(
255 net::URLRequest* url_request, 255 net::URLRequest* url_request,
256 ScheduledResourceRequest* request) { 256 ScheduledResourceRequest* request) {
257 if (ShouldStartRequest(request) == START_REQUEST) { 257 if (ShouldStartRequest(request) == START_REQUEST)
258 StartRequest(request); 258 StartRequest(request);
259 } else { 259 else
260 pending_requests_.Insert(request); 260 pending_requests_.Insert(request);
261 } 261 SetRequestClassification(request, GetRequestClassification(request));
262 } 262 }
263 263
264 void RemoveRequest(ScheduledResourceRequest* request) { 264 void RemoveRequest(ScheduledResourceRequest* request) {
265 if (pending_requests_.IsQueued(request)) { 265 if (pending_requests_.IsQueued(request)) {
266 pending_requests_.Erase(request); 266 pending_requests_.Erase(request);
267 DCHECK(!ContainsKey(in_flight_requests_, request)); 267 DCHECK(!ContainsKey(in_flight_requests_, request));
268 } else { 268 } else {
269 EraseInFlightRequest(request); 269 EraseInFlightRequest(request);
270 270
271 // Removing this request may have freed up another to load. 271 // Removing this request may have freed up another to load.
272 LoadAnyStartablePendingRequests(); 272 LoadAnyStartablePendingRequests();
273 } 273 }
274 } 274 }
275 275
276 RequestSet RemoveAllRequests() { 276 RequestSet RemoveAllRequests() {
277 RequestSet unowned_requests; 277 RequestSet unowned_requests;
278 for (RequestSet::iterator it = in_flight_requests_.begin(); 278 for (RequestSet::iterator it = in_flight_requests_.begin();
279 it != in_flight_requests_.end(); ++it) { 279 it != in_flight_requests_.end(); ++it) {
280 unowned_requests.insert(*it); 280 unowned_requests.insert(*it);
281 (*it)->set_accounted_as_delayable_request(false); 281 (*it)->set_classification(NORMAL_REQUEST);
282 } 282 }
283 ClearInFlightRequests(); 283 ClearInFlightRequests();
284 return unowned_requests; 284 return unowned_requests;
285 } 285 }
286 286
287 bool is_active() const { return is_visible_ || is_audible_; } 287 bool is_active() const { return is_visible_ || is_audible_; }
288 288
289 bool is_loaded() const { return is_loaded_; } 289 bool is_loaded() const { return is_loaded_; }
290 290
291 void OnAudibilityChanged(bool is_audible) { 291 void OnAudibilityChanged(bool is_audible) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 367
368 void ReprioritizeRequest(ScheduledResourceRequest* request, 368 void ReprioritizeRequest(ScheduledResourceRequest* request,
369 RequestPriorityParams old_priority_params, 369 RequestPriorityParams old_priority_params,
370 RequestPriorityParams new_priority_params) { 370 RequestPriorityParams new_priority_params) {
371 request->url_request()->SetPriority(new_priority_params.priority); 371 request->url_request()->SetPriority(new_priority_params.priority);
372 request->set_request_priority_params(new_priority_params); 372 request->set_request_priority_params(new_priority_params);
373 if (!pending_requests_.IsQueued(request)) { 373 if (!pending_requests_.IsQueued(request)) {
374 DCHECK(ContainsKey(in_flight_requests_, request)); 374 DCHECK(ContainsKey(in_flight_requests_, request));
375 // The priority and SPDY support may have changed, so update the 375 // The priority and SPDY support may have changed, so update the
376 // delayable count. 376 // delayable count.
377 SetRequestDelayable(request, IsDelayableRequest(request)); 377 SetRequestClassification(request, GetRequestClassification(request));
378 // Request has already started. 378 // Request has already started.
379 return; 379 return;
380 } 380 }
381 381
382 pending_requests_.Erase(request); 382 pending_requests_.Erase(request);
383 pending_requests_.Insert(request); 383 pending_requests_.Insert(request);
384 384
385 if (new_priority_params.priority > old_priority_params.priority) { 385 if (new_priority_params.priority > old_priority_params.priority) {
386 // Check if this request is now able to load at its new priority. 386 // Check if this request is now able to load at its new priority.
387 LoadAnyStartablePendingRequests(); 387 LoadAnyStartablePendingRequests();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 434
435 private: 435 private:
436 enum ShouldStartReqResult { 436 enum ShouldStartReqResult {
437 DO_NOT_START_REQUEST_AND_STOP_SEARCHING, 437 DO_NOT_START_REQUEST_AND_STOP_SEARCHING,
438 DO_NOT_START_REQUEST_AND_KEEP_SEARCHING, 438 DO_NOT_START_REQUEST_AND_KEEP_SEARCHING,
439 START_REQUEST, 439 START_REQUEST,
440 }; 440 };
441 441
442 void InsertInFlightRequest(ScheduledResourceRequest* request) { 442 void InsertInFlightRequest(ScheduledResourceRequest* request) {
443 in_flight_requests_.insert(request); 443 in_flight_requests_.insert(request);
444 if (IsDelayableRequest(request)) 444 SetRequestClassification(request, GetRequestClassification(request));
445 SetRequestDelayable(request, true);
446 } 445 }
447 446
448 void EraseInFlightRequest(ScheduledResourceRequest* request) { 447 void EraseInFlightRequest(ScheduledResourceRequest* request) {
449 size_t erased = in_flight_requests_.erase(request); 448 size_t erased = in_flight_requests_.erase(request);
450 DCHECK_EQ(1u, erased); 449 DCHECK_EQ(1u, erased);
451 SetRequestDelayable(request, false); 450 // Clear any special state that we were tracking for this request.
452 DCHECK_LE(total_delayable_count_, in_flight_requests_.size()); 451 SetRequestClassification(request, NORMAL_REQUEST);
453 } 452 }
454 453
455 void ClearInFlightRequests() { 454 void ClearInFlightRequests() {
456 in_flight_requests_.clear(); 455 in_flight_requests_.clear();
457 total_delayable_count_ = 0; 456 in_flight_delayable_count_ = 0;
457 total_layout_blocking_count_ = 0;
458 } 458 }
459 459
460 bool IsDelayableRequest(ScheduledResourceRequest* request) { 460 size_t CountRequestsWithClassification(
461 const RequestClassification classification, const bool include_pending) {
462 size_t classification_request_count = 0;
463 for (RequestSet::const_iterator it = in_flight_requests_.begin();
464 it != in_flight_requests_.end(); ++it) {
465 if ((*it)->classification() == classification)
466 classification_request_count++;
467 }
468 if (include_pending) {
469 for (RequestQueue::NetQueue::const_iterator
470 it = pending_requests_.GetNextHighestIterator();
471 it != pending_requests_.End(); ++it) {
472 if ((*it)->classification() == classification)
473 classification_request_count++;
474 }
475 }
476 return classification_request_count;
477 }
478
479 void SetRequestClassification(ScheduledResourceRequest* request,
480 RequestClassification classification) {
481 RequestClassification old_classification = request->classification();
482 if (old_classification == classification)
483 return;
484
485 bool in_flight = !pending_requests_.IsQueued(request);
mmenke 2014/08/18 20:59:43 This isn't used.
Pat Meenan 2014/08/20 14:57:31 Done.
486
487 if (old_classification == IN_FLIGHT_DELAYABLE_REQUEST)
488 in_flight_delayable_count_--;
489 if (old_classification == LAYOUT_BLOCKING_REQUEST)
490 total_layout_blocking_count_--;
491
492 if (classification == IN_FLIGHT_DELAYABLE_REQUEST)
493 in_flight_delayable_count_++;
494 if (classification == LAYOUT_BLOCKING_REQUEST)
495 total_layout_blocking_count_++;
496
497 request->set_classification(classification);
498 DCHECK_EQ(
499 CountRequestsWithClassification(IN_FLIGHT_DELAYABLE_REQUEST, false),
500 in_flight_delayable_count_);
501 DCHECK_EQ(CountRequestsWithClassification(LAYOUT_BLOCKING_REQUEST, true),
502 total_layout_blocking_count_);
503 }
504
505 RequestClassification GetRequestClassification(
mmenke 2014/08/18 20:59:43 Still think we should reconsider this name, to mak
Pat Meenan 2014/08/20 14:57:32 Done. Changed it to ClassifyRequest() which better
506 ScheduledResourceRequest* request) {
507 // If a request is already marked as layout-blocking make sure to keep the
508 // classification across redirects unless the priority was lowered.
509 if (request->classification() == LAYOUT_BLOCKING_REQUEST &&
510 request->url_request()->priority() >= net::LOW) {
511 return LAYOUT_BLOCKING_REQUEST;
512 }
513
514 if (!has_body_ && request->url_request()->priority() >= net::LOW)
515 return LAYOUT_BLOCKING_REQUEST;
516
461 if (request->url_request()->priority() < net::LOW) { 517 if (request->url_request()->priority() < net::LOW) {
462 net::HostPortPair host_port_pair = 518 net::HostPortPair host_port_pair =
463 net::HostPortPair::FromURL(request->url_request()->url()); 519 net::HostPortPair::FromURL(request->url_request()->url());
464 net::HttpServerProperties& http_server_properties = 520 net::HttpServerProperties& http_server_properties =
465 *request->url_request()->context()->http_server_properties(); 521 *request->url_request()->context()->http_server_properties();
466 if (!http_server_properties.SupportsSpdy(host_port_pair)) { 522 if (!http_server_properties.SupportsSpdy(host_port_pair) &&
467 return true; 523 !pending_requests_.IsQueued(request)) {
mmenke 2014/08/18 20:59:42 Can we check in_flight_requests_ instead? Seems w
Pat Meenan 2014/08/20 14:57:32 Done.
524 return IN_FLIGHT_DELAYABLE_REQUEST;
468 } 525 }
469 } 526 }
470 return false; 527 return NORMAL_REQUEST;
471 }
472
473 void SetRequestDelayable(ScheduledResourceRequest* request,
474 bool delayable) {
475 if (request->accounted_as_delayable_request() == delayable)
476 return;
477 if (delayable)
478 total_delayable_count_++;
479 else
480 total_delayable_count_--;
481 request->set_accounted_as_delayable_request(delayable);
482 } 528 }
483 529
484 bool ShouldKeepSearching( 530 bool ShouldKeepSearching(
485 const net::HostPortPair& active_request_host) const { 531 const net::HostPortPair& active_request_host) const {
486 size_t same_host_count = 0; 532 size_t same_host_count = 0;
487 for (RequestSet::const_iterator it = in_flight_requests_.begin(); 533 for (RequestSet::const_iterator it = in_flight_requests_.begin();
488 it != in_flight_requests_.end(); ++it) { 534 it != in_flight_requests_.end(); ++it) {
489 net::HostPortPair host_port_pair = 535 net::HostPortPair host_port_pair =
490 net::HostPortPair::FromURL((*it)->url_request()->url()); 536 net::HostPortPair::FromURL((*it)->url_request()->url());
491 if (active_request_host.Equals(host_port_pair)) { 537 if (active_request_host.Equals(host_port_pair)) {
492 same_host_count++; 538 same_host_count++;
493 if (same_host_count >= kMaxNumDelayableRequestsPerHost) 539 if (same_host_count >= kMaxNumDelayableRequestsPerHost)
494 return true; 540 return true;
495 } 541 }
496 } 542 }
497 return false; 543 return false;
498 } 544 }
499 545
500 void StartRequest(ScheduledResourceRequest* request) { 546 void StartRequest(ScheduledResourceRequest* request) {
501 InsertInFlightRequest(request); 547 InsertInFlightRequest(request);
502 request->Start(); 548 request->Start();
503 } 549 }
504 550
505 // ShouldStartRequest is the main scheduling algorithm. 551 // ShouldStartRequest is the main scheduling algorithm.
506 // 552 //
507 // Requests are categorized into three categories: 553 // Requests are evaluated on five attributes:
508 // 554 //
509 // 1. Non-delayable requests: 555 // 1. Non-delayable requests:
510 // * Synchronous requests. 556 // * Synchronous requests.
511 // * Non-HTTP[S] requests. 557 // * Non-HTTP[S] requests.
512 // 558 //
513 // 2. Requests to SPDY-capable origin servers. 559 // 2. Requests to SPDY-capable origin servers.
514 // 560 //
515 // 3. High-priority requests: 561 // 3. High-priority requests:
516 // * Higher priority requests (>= net::LOW). 562 // * Higher priority requests (>= net::LOW).
517 // 563 //
518 // 4. Low priority requests 564 // 4. Layout-blocking requests:
565 // * High-priority requests initiated before the renderer has a <body>.
566 //
567 // 5. Low priority requests
519 // 568 //
520 // The following rules are followed: 569 // The following rules are followed:
521 // 570 //
522 // ACTIVE_AND_LOADING and UNTHROTTLED Clients follow these rules: 571 // ACTIVE_AND_LOADING and UNTHROTTLED Clients follow these rules:
523 // * Non-delayable, High-priority and SDPY capable requests are issued 572 // * Non-delayable, High-priority and SPDY capable requests are issued
524 // immediately 573 // immediately.
525 // * If no high priority requests are in flight, start loading low priority
526 // requests.
527 // * Low priority requests are delayable. 574 // * Low priority requests are delayable.
528 // * Once the renderer has a <body>, start loading delayable requests. 575 // * Allow one delayable request to load at a time while layout-blocking
576 // requests are loading.
577 // * If no high priority or layout-blocking requests are in flight, start
578 // loading delayable requests.
529 // * Never exceed 10 delayable requests in flight per client. 579 // * Never exceed 10 delayable requests in flight per client.
530 // * Never exceed 6 delayable requests for a given host. 580 // * Never exceed 6 delayable requests for a given host.
531 // * Prior to <body>, allow one delayable request to load at a time.
532 // 581 //
533 // THROTTLED Clients follow these rules: 582 // THROTTLED Clients follow these rules:
534 // * Non-delayable and SPDY-capable requests are issued immediately. 583 // * Non-delayable and SPDY-capable requests are issued immediately.
535 // * At most one non-SPDY request will be issued per THROTTLED Client 584 // * At most one non-SPDY request will be issued per THROTTLED Client
536 // * If no high priority requests are in flight, start loading low priority 585 // * If no high priority requests are in flight, start loading low priority
537 // requests. 586 // requests.
538 // 587 //
539 // COALESCED Clients never load requests, with the following exceptions: 588 // COALESCED Clients never load requests, with the following exceptions:
540 // * Non-delayable requests are issued imediately. 589 // * Non-delayable requests are issued imediately.
541 // * On a (currently 5 second) heart beat, they load all requests as an 590 // * On a (currently 5 second) heart beat, they load all requests as an
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 if (http_server_properties.SupportsSpdy(host_port_pair)) { 627 if (http_server_properties.SupportsSpdy(host_port_pair)) {
579 return START_REQUEST; 628 return START_REQUEST;
580 } 629 }
581 630
582 if (throttle_state_ == THROTTLED && 631 if (throttle_state_ == THROTTLED &&
583 in_flight_requests_.size() >= kMaxNumThrottledRequestsPerClient) { 632 in_flight_requests_.size() >= kMaxNumThrottledRequestsPerClient) {
584 // There may still be SPDY-capable requests that should be issued. 633 // There may still be SPDY-capable requests that should be issued.
585 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; 634 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING;
586 } 635 }
587 636
637 // High-priority and layout-blocking requests.
588 if (url_request.priority() >= net::LOW) { 638 if (url_request.priority() >= net::LOW) {
589 return START_REQUEST; 639 return START_REQUEST;
590 } 640 }
591 641
592 size_t num_delayable_requests_in_flight = total_delayable_count_; 642 if (in_flight_delayable_count_ >= kMaxNumDelayableRequestsPerClient) {
593 if (num_delayable_requests_in_flight >= kMaxNumDelayableRequestsPerClient) {
594 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; 643 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING;
595 } 644 }
596 645
597 if (ShouldKeepSearching(host_port_pair)) { 646 if (ShouldKeepSearching(host_port_pair)) {
598 // There may be other requests for other hosts we'd allow, 647 // There may be other requests for other hosts we'd allow,
599 // so keep checking. 648 // so keep checking.
600 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; 649 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING;
601 } 650 }
602 651
603 bool have_immediate_requests_in_flight = 652 bool have_immediate_requests_in_flight =
604 in_flight_requests_.size() > num_delayable_requests_in_flight; 653 in_flight_requests_.size() > in_flight_delayable_count_;
605 if (have_immediate_requests_in_flight && !has_body_ && 654 if (have_immediate_requests_in_flight &&
606 num_delayable_requests_in_flight != 0) { 655 total_layout_blocking_count_ != 0 &&
656 in_flight_delayable_count_ != 0) {
607 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; 657 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING;
608 } 658 }
609 659
610 return START_REQUEST; 660 return START_REQUEST;
611 } 661 }
612 662
613 void LoadAnyStartablePendingRequests() { 663 void LoadAnyStartablePendingRequests() {
614 // We iterate through all the pending requests, starting with the highest 664 // We iterate through all the pending requests, starting with the highest
615 // priority one. For each entry, one of three things can happen: 665 // priority one. For each entry, one of three things can happen:
616 // 1) We start the request, remove it from the list, and keep checking. 666 // 1) We start the request, remove it from the list, and keep checking.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 bool is_audible_; 700 bool is_audible_;
651 bool is_visible_; 701 bool is_visible_;
652 bool is_loaded_; 702 bool is_loaded_;
653 bool is_paused_; 703 bool is_paused_;
654 bool has_body_; 704 bool has_body_;
655 bool using_spdy_proxy_; 705 bool using_spdy_proxy_;
656 RequestQueue pending_requests_; 706 RequestQueue pending_requests_;
657 RequestSet in_flight_requests_; 707 RequestSet in_flight_requests_;
658 ResourceScheduler* scheduler_; 708 ResourceScheduler* scheduler_;
659 // The number of delayable in-flight requests. 709 // The number of delayable in-flight requests.
660 size_t total_delayable_count_; 710 size_t in_flight_delayable_count_;
711 // The number of layout-blocking in-flight requests.
712 size_t total_layout_blocking_count_;
661 ResourceScheduler::ClientThrottleState throttle_state_; 713 ResourceScheduler::ClientThrottleState throttle_state_;
662 }; 714 };
663 715
664 ResourceScheduler::ResourceScheduler() 716 ResourceScheduler::ResourceScheduler()
665 : should_coalesce_(false), 717 : should_coalesce_(false),
666 should_throttle_(false), 718 should_throttle_(false),
667 active_clients_loading_(0), 719 active_clients_loading_(0),
668 coalesced_clients_(0), 720 coalesced_clients_(0),
669 coalescing_timer_(new base::Timer(true /* retain_user_task */, 721 coalescing_timer_(new base::Timer(true /* retain_user_task */,
670 true /* is_repeating */)) { 722 true /* is_repeating */)) {
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 client->ReprioritizeRequest( 1012 client->ReprioritizeRequest(
961 request, old_priority_params, new_priority_params); 1013 request, old_priority_params, new_priority_params);
962 } 1014 }
963 1015
964 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( 1016 ResourceScheduler::ClientId ResourceScheduler::MakeClientId(
965 int child_id, int route_id) { 1017 int child_id, int route_id) {
966 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; 1018 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id;
967 } 1019 }
968 1020
969 } // namespace content 1021 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_scheduler.h ('k') | content/browser/loader/resource_scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698