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

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: Fixed tracking of pending layout-blocking requests 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 category_(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 RequestCategory category() const {
163 return accounted_as_delayable_request_; 163 return category_;
164 } 164 }
165 void set_accounted_as_delayable_request(bool accounted) { 165 void set_category(RequestCategory category) {
166 accounted_as_delayable_request_ = accounted; 166 category_ = category;
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 RequestCategory category_;
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 // We need to keep track of all layout-blocking requests, not just ones
262 // that are in-flight. StartRequest() updates the accounting for ones
263 // that are in-flight and this catches the ones that are queued. We also
264 // need to do the accounting after it is in the queue so the DCHECK to
265 // validate the counts is accurate.
mmenke 2014/08/15 19:53:40 nit: Don't use we in comments, since it's ambiguo
Pat Meenan 2014/08/15 21:39:31 Done.
266 if (GetRequestCategory(request) == LAYOUT_BLOCKING_REQUEST)
267 SetRequestCategory(request, LAYOUT_BLOCKING_REQUEST);
mmenke 2014/08/15 19:53:40 Think SetRequestCategory(GetRequestCategory()) is
mmenke 2014/08/15 19:53:40 I think it's weird that layout blocking requests a
Pat Meenan 2014/08/15 21:39:31 Agreed. I could set the category on everything al
mmenke 2014/08/18 16:30:20 I'm on the fence... Clarity reduces the change of
Pat Meenan 2014/08/18 18:29:57 I think I found a cleaner way to solve it. I chan
261 } 268 }
262 } 269 }
263 270
264 void RemoveRequest(ScheduledResourceRequest* request) { 271 void RemoveRequest(ScheduledResourceRequest* request) {
265 if (pending_requests_.IsQueued(request)) { 272 if (pending_requests_.IsQueued(request)) {
266 pending_requests_.Erase(request); 273 pending_requests_.Erase(request);
267 DCHECK(!ContainsKey(in_flight_requests_, request)); 274 DCHECK(!ContainsKey(in_flight_requests_, request));
268 } else { 275 } else {
269 EraseInFlightRequest(request); 276 EraseInFlightRequest(request);
270 277
271 // Removing this request may have freed up another to load. 278 // Removing this request may have freed up another to load.
272 LoadAnyStartablePendingRequests(); 279 LoadAnyStartablePendingRequests();
273 } 280 }
274 } 281 }
275 282
276 RequestSet RemoveAllRequests() { 283 RequestSet RemoveAllRequests() {
277 RequestSet unowned_requests; 284 RequestSet unowned_requests;
278 for (RequestSet::iterator it = in_flight_requests_.begin(); 285 for (RequestSet::iterator it = in_flight_requests_.begin();
279 it != in_flight_requests_.end(); ++it) { 286 it != in_flight_requests_.end(); ++it) {
280 unowned_requests.insert(*it); 287 unowned_requests.insert(*it);
281 (*it)->set_accounted_as_delayable_request(false); 288 (*it)->set_category(NORMAL_REQUEST);
282 } 289 }
283 ClearInFlightRequests(); 290 ClearInFlightRequests();
284 return unowned_requests; 291 return unowned_requests;
285 } 292 }
286 293
287 bool is_active() const { return is_visible_ || is_audible_; } 294 bool is_active() const { return is_visible_ || is_audible_; }
288 295
289 bool is_loaded() const { return is_loaded_; } 296 bool is_loaded() const { return is_loaded_; }
290 297
291 void OnAudibilityChanged(bool is_audible) { 298 void OnAudibilityChanged(bool is_audible) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 374
368 void ReprioritizeRequest(ScheduledResourceRequest* request, 375 void ReprioritizeRequest(ScheduledResourceRequest* request,
369 RequestPriorityParams old_priority_params, 376 RequestPriorityParams old_priority_params,
370 RequestPriorityParams new_priority_params) { 377 RequestPriorityParams new_priority_params) {
371 request->url_request()->SetPriority(new_priority_params.priority); 378 request->url_request()->SetPriority(new_priority_params.priority);
372 request->set_request_priority_params(new_priority_params); 379 request->set_request_priority_params(new_priority_params);
373 if (!pending_requests_.IsQueued(request)) { 380 if (!pending_requests_.IsQueued(request)) {
374 DCHECK(ContainsKey(in_flight_requests_, request)); 381 DCHECK(ContainsKey(in_flight_requests_, request));
375 // The priority and SPDY support may have changed, so update the 382 // The priority and SPDY support may have changed, so update the
376 // delayable count. 383 // delayable count.
377 SetRequestDelayable(request, IsDelayableRequest(request)); 384 SetRequestCategory(request, GetRequestCategory(request));
378 // Request has already started. 385 // Request has already started.
379 return; 386 return;
380 } 387 }
381 388
382 pending_requests_.Erase(request); 389 pending_requests_.Erase(request);
383 pending_requests_.Insert(request); 390 pending_requests_.Insert(request);
384 391
385 if (new_priority_params.priority > old_priority_params.priority) { 392 if (new_priority_params.priority > old_priority_params.priority) {
386 // Check if this request is now able to load at its new priority. 393 // Check if this request is now able to load at its new priority.
387 LoadAnyStartablePendingRequests(); 394 LoadAnyStartablePendingRequests();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 441
435 private: 442 private:
436 enum ShouldStartReqResult { 443 enum ShouldStartReqResult {
437 DO_NOT_START_REQUEST_AND_STOP_SEARCHING, 444 DO_NOT_START_REQUEST_AND_STOP_SEARCHING,
438 DO_NOT_START_REQUEST_AND_KEEP_SEARCHING, 445 DO_NOT_START_REQUEST_AND_KEEP_SEARCHING,
439 START_REQUEST, 446 START_REQUEST,
440 }; 447 };
441 448
442 void InsertInFlightRequest(ScheduledResourceRequest* request) { 449 void InsertInFlightRequest(ScheduledResourceRequest* request) {
443 in_flight_requests_.insert(request); 450 in_flight_requests_.insert(request);
444 if (IsDelayableRequest(request)) 451 SetRequestCategory(request, GetRequestCategory(request));
445 SetRequestDelayable(request, true);
446 } 452 }
447 453
448 void EraseInFlightRequest(ScheduledResourceRequest* request) { 454 void EraseInFlightRequest(ScheduledResourceRequest* request) {
449 size_t erased = in_flight_requests_.erase(request); 455 size_t erased = in_flight_requests_.erase(request);
450 DCHECK_EQ(1u, erased); 456 DCHECK_EQ(1u, erased);
451 SetRequestDelayable(request, false); 457 // Clear any special state that we were tracking for this request.
452 DCHECK_LE(total_delayable_count_, in_flight_requests_.size()); 458 SetRequestCategory(request, NORMAL_REQUEST);
453 } 459 }
454 460
455 void ClearInFlightRequests() { 461 void ClearInFlightRequests() {
456 in_flight_requests_.clear(); 462 in_flight_requests_.clear();
457 total_delayable_count_ = 0; 463 in_flight_delayable_count_ = 0;
464 total_layout_blocking_count_ = 0;
458 } 465 }
459 466
460 bool IsDelayableRequest(ScheduledResourceRequest* request) { 467 size_t CountRequestsInCategory(RequestCategory category,
468 bool include_pending) {
mmenke 2014/08/15 19:53:40 nit: const
Pat Meenan 2014/08/15 21:39:32 Done.
469 size_t category_request_count = 0;
470 for (RequestSet::const_iterator it = in_flight_requests_.begin();
471 it != in_flight_requests_.end(); ++it) {
472 if ((*it)->category() == category)
473 category_request_count++;
474 }
475 if (include_pending) {
476 for (RequestQueue::NetQueue::const_iterator
477 it = pending_requests_.GetNextHighestIterator();
478 it != pending_requests_.End(); ++it) {
479 if ((*it)->category() == category)
480 category_request_count++;
481 }
482 }
483 return category_request_count;
484 }
485
486 void SetRequestCategory(ScheduledResourceRequest* request,
487 RequestCategory category) {
488 RequestCategory old_category = request->category();
489 if (old_category == category)
490 return;
491
492 if (old_category == DELAYABLE_REQUEST)
493 in_flight_delayable_count_--;
494 if (old_category == LAYOUT_BLOCKING_REQUEST)
495 total_layout_blocking_count_--;
496
497 if (category == DELAYABLE_REQUEST)
498 in_flight_delayable_count_++;
499 if (category == LAYOUT_BLOCKING_REQUEST)
500 total_layout_blocking_count_++;
501
502 request->set_category(category);
503 DCHECK_EQ(CountRequestsInCategory(DELAYABLE_REQUEST, false),
504 in_flight_delayable_count_);
505 DCHECK_EQ(CountRequestsInCategory(LAYOUT_BLOCKING_REQUEST, true),
506 total_layout_blocking_count_);
507 }
508
509 RequestCategory GetRequestCategory(ScheduledResourceRequest* request) {
510 // If a request is already marked as layout-blocking make sure to keep the
511 // category across redirects unless we chose to lower the priority of the
mmenke 2014/08/15 19:53:40 nit: Don't use we in comments.
Pat Meenan 2014/08/15 21:39:31 Done.
512 // request.
513 if (request->category() == LAYOUT_BLOCKING_REQUEST &&
514 request->url_request()->priority() >= net::LOW)
515 return LAYOUT_BLOCKING_REQUEST;
mmenke 2014/08/15 19:53:40 nit: Use braces when the conditional takes up mor
Pat Meenan 2014/08/15 21:39:31 Done.
516
517 if (!has_body_ && request->url_request()->priority() >= net::LOW)
518 return LAYOUT_BLOCKING_REQUEST;
461 if (request->url_request()->priority() < net::LOW) { 519 if (request->url_request()->priority() < net::LOW) {
462 net::HostPortPair host_port_pair = 520 net::HostPortPair host_port_pair =
463 net::HostPortPair::FromURL(request->url_request()->url()); 521 net::HostPortPair::FromURL(request->url_request()->url());
464 net::HttpServerProperties& http_server_properties = 522 net::HttpServerProperties& http_server_properties =
465 *request->url_request()->context()->http_server_properties(); 523 *request->url_request()->context()->http_server_properties();
466 if (!http_server_properties.SupportsSpdy(host_port_pair)) { 524 if (!http_server_properties.SupportsSpdy(host_port_pair)) {
467 return true; 525 return DELAYABLE_REQUEST;
468 } 526 }
469 } 527 }
470 return false; 528 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 } 529 }
483 530
484 bool ShouldKeepSearching( 531 bool ShouldKeepSearching(
485 const net::HostPortPair& active_request_host) const { 532 const net::HostPortPair& active_request_host) const {
486 size_t same_host_count = 0; 533 size_t same_host_count = 0;
487 for (RequestSet::const_iterator it = in_flight_requests_.begin(); 534 for (RequestSet::const_iterator it = in_flight_requests_.begin();
488 it != in_flight_requests_.end(); ++it) { 535 it != in_flight_requests_.end(); ++it) {
489 net::HostPortPair host_port_pair = 536 net::HostPortPair host_port_pair =
490 net::HostPortPair::FromURL((*it)->url_request()->url()); 537 net::HostPortPair::FromURL((*it)->url_request()->url());
491 if (active_request_host.Equals(host_port_pair)) { 538 if (active_request_host.Equals(host_port_pair)) {
492 same_host_count++; 539 same_host_count++;
493 if (same_host_count >= kMaxNumDelayableRequestsPerHost) 540 if (same_host_count >= kMaxNumDelayableRequestsPerHost)
494 return true; 541 return true;
495 } 542 }
496 } 543 }
497 return false; 544 return false;
498 } 545 }
499 546
500 void StartRequest(ScheduledResourceRequest* request) { 547 void StartRequest(ScheduledResourceRequest* request) {
501 InsertInFlightRequest(request); 548 InsertInFlightRequest(request);
502 request->Start(); 549 request->Start();
503 } 550 }
504 551
505 // ShouldStartRequest is the main scheduling algorithm. 552 // ShouldStartRequest is the main scheduling algorithm.
506 // 553 //
507 // Requests are categorized into three categories: 554 // Requests are categorized into five categories:
508 // 555 //
509 // 1. Non-delayable requests: 556 // 1. Non-delayable requests:
510 // * Synchronous requests. 557 // * Synchronous requests.
511 // * Non-HTTP[S] requests. 558 // * Non-HTTP[S] requests.
512 // 559 //
513 // 2. Requests to SPDY-capable origin servers. 560 // 2. Requests to SPDY-capable origin servers.
514 // 561 //
515 // 3. High-priority requests: 562 // 3. High-priority requests:
516 // * Higher priority requests (>= net::LOW). 563 // * Higher priority requests (>= net::LOW).
517 // 564 //
518 // 4. Low priority requests 565 // 4. Layout-blocking requests:
566 // * High-priority requests initiated before the renderer has a <body>.
567 //
568 // 5. Low priority requests
519 // 569 //
520 // The following rules are followed: 570 // The following rules are followed:
521 // 571 //
522 // ACTIVE_AND_LOADING and UNTHROTTLED Clients follow these rules: 572 // ACTIVE_AND_LOADING and UNTHROTTLED Clients follow these rules:
523 // * Non-delayable, High-priority and SDPY capable requests are issued 573 // * Non-delayable, High-priority and SPDY capable requests are issued
524 // immediately 574 // immediately.
525 // * If no high priority requests are in flight, start loading low priority 575 // * If no high priority requests are in flight, start loading low priority
526 // requests. 576 // requests.
527 // * Low priority requests are delayable. 577 // * Low priority requests are delayable.
528 // * Once the renderer has a <body>, start loading delayable requests. 578 // * Allow one delayable request to load at a time while layout-blocking
579 // requests are loading.
580 // * Once all layout-blocking requests have finished loading, start loading
581 // delayable requests.
529 // * Never exceed 10 delayable requests in flight per client. 582 // * Never exceed 10 delayable requests in flight per client.
530 // * Never exceed 6 delayable requests for a given host. 583 // * Never exceed 6 delayable requests for a given host.
531 // * Prior to <body>, allow one delayable request to load at a time.
532 // 584 //
533 // THROTTLED Clients follow these rules: 585 // THROTTLED Clients follow these rules:
534 // * Non-delayable and SPDY-capable requests are issued immediately. 586 // * Non-delayable and SPDY-capable requests are issued immediately.
535 // * At most one non-SPDY request will be issued per THROTTLED Client 587 // * 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 588 // * If no high priority requests are in flight, start loading low priority
537 // requests. 589 // requests.
538 // 590 //
539 // COALESCED Clients never load requests, with the following exceptions: 591 // COALESCED Clients never load requests, with the following exceptions:
540 // * Non-delayable requests are issued imediately. 592 // * Non-delayable requests are issued imediately.
541 // * On a (currently 5 second) heart beat, they load all requests as an 593 // * 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)) { 630 if (http_server_properties.SupportsSpdy(host_port_pair)) {
579 return START_REQUEST; 631 return START_REQUEST;
580 } 632 }
581 633
582 if (throttle_state_ == THROTTLED && 634 if (throttle_state_ == THROTTLED &&
583 in_flight_requests_.size() >= kMaxNumThrottledRequestsPerClient) { 635 in_flight_requests_.size() >= kMaxNumThrottledRequestsPerClient) {
584 // There may still be SPDY-capable requests that should be issued. 636 // There may still be SPDY-capable requests that should be issued.
585 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; 637 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING;
586 } 638 }
587 639
640 // High-priority and layout-blocking requests.
588 if (url_request.priority() >= net::LOW) { 641 if (url_request.priority() >= net::LOW) {
589 return START_REQUEST; 642 return START_REQUEST;
590 } 643 }
591 644
592 size_t num_delayable_requests_in_flight = total_delayable_count_; 645 if (in_flight_delayable_count_ >= kMaxNumDelayableRequestsPerClient) {
593 if (num_delayable_requests_in_flight >= kMaxNumDelayableRequestsPerClient) {
594 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; 646 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING;
595 } 647 }
596 648
597 if (ShouldKeepSearching(host_port_pair)) { 649 if (ShouldKeepSearching(host_port_pair)) {
598 // There may be other requests for other hosts we'd allow, 650 // There may be other requests for other hosts we'd allow,
599 // so keep checking. 651 // so keep checking.
600 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; 652 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING;
601 } 653 }
602 654
603 bool have_immediate_requests_in_flight = 655 bool have_immediate_requests_in_flight =
604 in_flight_requests_.size() > num_delayable_requests_in_flight; 656 in_flight_requests_.size() > in_flight_delayable_count_;
mmenke 2014/08/15 19:53:40 Random comment, no need to worry about in this CL:
Pat Meenan 2014/08/15 21:39:31 SPDY handling across multiple connections in gener
605 if (have_immediate_requests_in_flight && !has_body_ && 657 if (have_immediate_requests_in_flight &&
606 num_delayable_requests_in_flight != 0) { 658 total_layout_blocking_count_ != 0 &&
659 in_flight_delayable_count_ != 0) {
607 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; 660 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING;
608 } 661 }
609 662
610 return START_REQUEST; 663 return START_REQUEST;
611 } 664 }
612 665
613 void LoadAnyStartablePendingRequests() { 666 void LoadAnyStartablePendingRequests() {
614 // We iterate through all the pending requests, starting with the highest 667 // We iterate through all the pending requests, starting with the highest
615 // priority one. For each entry, one of three things can happen: 668 // 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. 669 // 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_; 703 bool is_audible_;
651 bool is_visible_; 704 bool is_visible_;
652 bool is_loaded_; 705 bool is_loaded_;
653 bool is_paused_; 706 bool is_paused_;
654 bool has_body_; 707 bool has_body_;
655 bool using_spdy_proxy_; 708 bool using_spdy_proxy_;
656 RequestQueue pending_requests_; 709 RequestQueue pending_requests_;
657 RequestSet in_flight_requests_; 710 RequestSet in_flight_requests_;
658 ResourceScheduler* scheduler_; 711 ResourceScheduler* scheduler_;
659 // The number of delayable in-flight requests. 712 // The number of delayable in-flight requests.
660 size_t total_delayable_count_; 713 size_t in_flight_delayable_count_;
714 // The number of layout-blocking in-flight requests.
715 size_t total_layout_blocking_count_;
661 ResourceScheduler::ClientThrottleState throttle_state_; 716 ResourceScheduler::ClientThrottleState throttle_state_;
662 }; 717 };
663 718
664 ResourceScheduler::ResourceScheduler() 719 ResourceScheduler::ResourceScheduler()
665 : should_coalesce_(false), 720 : should_coalesce_(false),
666 should_throttle_(false), 721 should_throttle_(false),
667 active_clients_loading_(0), 722 active_clients_loading_(0),
668 coalesced_clients_(0), 723 coalesced_clients_(0),
669 coalescing_timer_(new base::Timer(true /* retain_user_task */, 724 coalescing_timer_(new base::Timer(true /* retain_user_task */,
670 true /* is_repeating */)) { 725 true /* is_repeating */)) {
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 client->ReprioritizeRequest( 1015 client->ReprioritizeRequest(
961 request, old_priority_params, new_priority_params); 1016 request, old_priority_params, new_priority_params);
962 } 1017 }
963 1018
964 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( 1019 ResourceScheduler::ClientId ResourceScheduler::MakeClientId(
965 int child_id, int route_id) { 1020 int child_id, int route_id) {
966 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; 1021 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id;
967 } 1022 }
968 1023
969 } // namespace content 1024 } // 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