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