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 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 } | 466 } |
467 } | 467 } |
468 | 468 |
469 void ReprioritizeRequest(ScheduledResourceRequest* request, | 469 void ReprioritizeRequest(ScheduledResourceRequest* request, |
470 RequestPriorityParams old_priority_params, | 470 RequestPriorityParams old_priority_params, |
471 RequestPriorityParams new_priority_params) { | 471 RequestPriorityParams new_priority_params) { |
472 request->url_request()->SetPriority(new_priority_params.priority); | 472 request->url_request()->SetPriority(new_priority_params.priority); |
473 request->set_request_priority_params(new_priority_params); | 473 request->set_request_priority_params(new_priority_params); |
474 if (!pending_requests_.IsQueued(request)) { | 474 if (!pending_requests_.IsQueued(request)) { |
475 DCHECK(ContainsKey(in_flight_requests_, request)); | 475 DCHECK(ContainsKey(in_flight_requests_, request)); |
476 // The priority and SPDY support may have changed, so update the | 476 // The priority of the request and priority support of the server may |
477 // delayable count. | 477 // have changed, so update the delayable count. |
478 SetRequestClassification(request, ClassifyRequest(request)); | 478 SetRequestClassification(request, ClassifyRequest(request)); |
479 // Request has already started. | 479 // Request has already started. |
480 return; | 480 return; |
481 } | 481 } |
482 | 482 |
483 pending_requests_.Erase(request); | 483 pending_requests_.Erase(request); |
484 pending_requests_.Insert(request); | 484 pending_requests_.Insert(request); |
485 | 485 |
486 if (new_priority_params.priority > old_priority_params.priority) { | 486 if (new_priority_params.priority > old_priority_params.priority) { |
487 // Check if this request is now able to load at its new priority. | 487 // Check if this request is now able to load at its new priority. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 } | 610 } |
611 | 611 |
612 if (!has_body_ && request->url_request()->priority() > net::LOW) | 612 if (!has_body_ && request->url_request()->priority() > net::LOW) |
613 return LAYOUT_BLOCKING_REQUEST; | 613 return LAYOUT_BLOCKING_REQUEST; |
614 | 614 |
615 if (request->url_request()->priority() < net::LOW) { | 615 if (request->url_request()->priority() < net::LOW) { |
616 net::HostPortPair host_port_pair = | 616 net::HostPortPair host_port_pair = |
617 net::HostPortPair::FromURL(request->url_request()->url()); | 617 net::HostPortPair::FromURL(request->url_request()->url()); |
618 net::HttpServerProperties& http_server_properties = | 618 net::HttpServerProperties& http_server_properties = |
619 *request->url_request()->context()->http_server_properties(); | 619 *request->url_request()->context()->http_server_properties(); |
620 if (!http_server_properties.SupportsSpdy(host_port_pair) && | 620 if (!http_server_properties.SupportsRequestPriority(host_port_pair) && |
621 ContainsKey(in_flight_requests_, request)) { | 621 ContainsKey(in_flight_requests_, request)) { |
622 return IN_FLIGHT_DELAYABLE_REQUEST; | 622 return IN_FLIGHT_DELAYABLE_REQUEST; |
623 } | 623 } |
624 } | 624 } |
625 return NORMAL_REQUEST; | 625 return NORMAL_REQUEST; |
626 } | 626 } |
627 | 627 |
628 bool ShouldKeepSearching( | 628 bool ShouldKeepSearching( |
629 const net::HostPortPair& active_request_host) const { | 629 const net::HostPortPair& active_request_host) const { |
630 size_t same_host_count = 0; | 630 size_t same_host_count = 0; |
(...skipping 16 matching lines...) Expand all Loading... |
647 } | 647 } |
648 | 648 |
649 // ShouldStartRequest is the main scheduling algorithm. | 649 // ShouldStartRequest is the main scheduling algorithm. |
650 // | 650 // |
651 // Requests are evaluated on five attributes: | 651 // Requests are evaluated on five attributes: |
652 // | 652 // |
653 // 1. Non-delayable requests: | 653 // 1. Non-delayable requests: |
654 // * Synchronous requests. | 654 // * Synchronous requests. |
655 // * Non-HTTP[S] requests. | 655 // * Non-HTTP[S] requests. |
656 // | 656 // |
657 // 2. Requests to SPDY-capable origin servers. | 657 // 2. Requests to request-priority-capable origin servers. |
658 // | 658 // |
659 // 3. High-priority requests: | 659 // 3. High-priority requests: |
660 // * Higher priority requests (>= net::LOW). | 660 // * Higher priority requests (>= net::LOW). |
661 // | 661 // |
662 // 4. Layout-blocking requests: | 662 // 4. Layout-blocking requests: |
663 // * High-priority requests (> net::LOW) initiated before the renderer has | 663 // * High-priority requests (> net::LOW) initiated before the renderer has |
664 // a <body>. | 664 // a <body>. |
665 // | 665 // |
666 // 5. Low priority requests | 666 // 5. Low priority requests |
667 // | 667 // |
668 // The following rules are followed: | 668 // The following rules are followed: |
669 // | 669 // |
670 // ACTIVE_AND_LOADING and UNTHROTTLED Clients follow these rules: | 670 // ACTIVE_AND_LOADING and UNTHROTTLED Clients follow these rules: |
671 // * Non-delayable, High-priority and SPDY capable requests are issued | 671 // * Non-delayable, High-priority and request-priority capable requests are |
672 // immediately. | 672 // issued immediately. |
673 // * Low priority requests are delayable. | 673 // * Low priority requests are delayable. |
674 // * Allow one delayable request to load at a time while layout-blocking | 674 // * Allow one delayable request to load at a time while layout-blocking |
675 // requests are loading or the body tag has not yet been parsed. | 675 // requests are loading or the body tag has not yet been parsed. |
676 // * If no high priority or layout-blocking requests are in flight, start | 676 // * If no high priority or layout-blocking requests are in flight, start |
677 // loading delayable requests. | 677 // loading delayable requests. |
678 // * Never exceed 10 delayable requests in flight per client. | 678 // * Never exceed 10 delayable requests in flight per client. |
679 // * Never exceed 6 delayable requests for a given host. | 679 // * Never exceed 6 delayable requests for a given host. |
680 // | 680 // |
681 // THROTTLED Clients follow these rules: | 681 // THROTTLED Clients follow these rules: |
682 // * Non-delayable and SPDY-capable requests are issued immediately. | 682 // * Non-delayable and request-priority-capable requests are issued |
683 // * At most one non-SPDY request will be issued per THROTTLED Client | 683 // immediately. |
| 684 // * At most one non-request-priority-capable request will be issued per |
| 685 // THROTTLED Client |
684 // * If no high priority requests are in flight, start loading low priority | 686 // * If no high priority requests are in flight, start loading low priority |
685 // requests. | 687 // requests. |
686 // | 688 // |
687 // COALESCED Clients never load requests, with the following exceptions: | 689 // COALESCED Clients never load requests, with the following exceptions: |
688 // * Non-delayable requests are issued imediately. | 690 // * Non-delayable requests are issued imediately. |
689 // * On a (currently 5 second) heart beat, they load all requests as an | 691 // * On a (currently 5 second) heart beat, they load all requests as an |
690 // UNTHROTTLED Client, and then return to the COALESCED state. | 692 // UNTHROTTLED Client, and then return to the COALESCED state. |
691 // * When an active Client makes a request, they are THROTTLED until the | 693 // * When an active Client makes a request, they are THROTTLED until the |
692 // active Client finishes loading. | 694 // active Client finishes loading. |
693 ShouldStartReqResult ShouldStartRequest( | 695 ShouldStartReqResult ShouldStartRequest( |
(...skipping 20 matching lines...) Expand all Loading... |
714 if (using_spdy_proxy_ && url_request.url().SchemeIs(url::kHttpScheme)) { | 716 if (using_spdy_proxy_ && url_request.url().SchemeIs(url::kHttpScheme)) { |
715 return START_REQUEST; | 717 return START_REQUEST; |
716 } | 718 } |
717 | 719 |
718 net::HostPortPair host_port_pair = | 720 net::HostPortPair host_port_pair = |
719 net::HostPortPair::FromURL(url_request.url()); | 721 net::HostPortPair::FromURL(url_request.url()); |
720 net::HttpServerProperties& http_server_properties = | 722 net::HttpServerProperties& http_server_properties = |
721 *url_request.context()->http_server_properties(); | 723 *url_request.context()->http_server_properties(); |
722 | 724 |
723 // TODO(willchan): We should really improve this algorithm as described in | 725 // TODO(willchan): We should really improve this algorithm as described in |
724 // crbug.com/164101. Also, theoretically we should not count a SPDY request | 726 // crbug.com/164101. Also, theoretically we should not count a |
725 // against the delayable requests limit. | 727 // request-priority capable request against the delayable requests limit. |
726 if (http_server_properties.SupportsSpdy(host_port_pair)) { | 728 if (http_server_properties.SupportsRequestPriority(host_port_pair)) { |
727 return START_REQUEST; | 729 return START_REQUEST; |
728 } | 730 } |
729 | 731 |
730 if (throttle_state_ == THROTTLED && | 732 if (throttle_state_ == THROTTLED && |
731 in_flight_requests_.size() >= kMaxNumThrottledRequestsPerClient) { | 733 in_flight_requests_.size() >= kMaxNumThrottledRequestsPerClient) { |
732 // There may still be SPDY-capable requests that should be issued. | 734 // There may still be request-priority-capable requests that should be |
| 735 // issued. |
733 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; | 736 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; |
734 } | 737 } |
735 | 738 |
736 // High-priority and layout-blocking requests. | 739 // High-priority and layout-blocking requests. |
737 if (url_request.priority() >= net::LOW) { | 740 if (url_request.priority() >= net::LOW) { |
738 return START_REQUEST; | 741 return START_REQUEST; |
739 } | 742 } |
740 | 743 |
741 if (in_flight_delayable_count_ >= kMaxNumDelayableRequestsPerClient) { | 744 if (in_flight_delayable_count_ >= kMaxNumDelayableRequestsPerClient) { |
742 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; | 745 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 client->ReprioritizeRequest( | 1143 client->ReprioritizeRequest( |
1141 request, old_priority_params, new_priority_params); | 1144 request, old_priority_params, new_priority_params); |
1142 } | 1145 } |
1143 | 1146 |
1144 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( | 1147 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( |
1145 int child_id, int route_id) { | 1148 int child_id, int route_id) { |
1146 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; | 1149 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; |
1147 } | 1150 } |
1148 | 1151 |
1149 } // namespace content | 1152 } // namespace content |
OLD | NEW |