Chromium Code Reviews| 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/base_switches.h" | |
| 10 #include "base/basictypes.h" | |
| 11 #include "base/command_line.h" | |
| 9 #include "base/metrics/field_trial.h" | 12 #include "base/metrics/field_trial.h" |
| 10 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 11 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 12 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/string_piece.h" | 16 #include "base/strings/string_piece.h" |
| 14 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 15 #include "content/common/resource_messages.h" | 18 #include "content/common/resource_messages.h" |
| 16 #include "content/browser/loader/resource_message_delegate.h" | 19 #include "content/browser/loader/resource_message_delegate.h" |
| 17 #include "content/public/browser/resource_controller.h" | 20 #include "content/public/browser/resource_controller.h" |
| 18 #include "content/public/browser/resource_request_info.h" | 21 #include "content/public/browser/resource_request_info.h" |
| 19 #include "content/public/browser/resource_throttle.h" | 22 #include "content/public/browser/resource_throttle.h" |
| 23 #include "content/public/common/content_switches.h" | |
| 20 #include "ipc/ipc_message_macros.h" | 24 #include "ipc/ipc_message_macros.h" |
| 21 #include "net/base/host_port_pair.h" | 25 #include "net/base/host_port_pair.h" |
| 22 #include "net/base/load_flags.h" | 26 #include "net/base/load_flags.h" |
| 23 #include "net/base/request_priority.h" | 27 #include "net/base/request_priority.h" |
| 24 #include "net/http/http_server_properties.h" | 28 #include "net/http/http_server_properties.h" |
| 25 #include "net/url_request/url_request.h" | 29 #include "net/url_request/url_request.h" |
| 26 #include "net/url_request/url_request_context.h" | 30 #include "net/url_request/url_request_context.h" |
| 27 | 31 |
| 28 namespace content { | 32 namespace content { |
| 29 | 33 |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 : is_audible_(is_audible), | 311 : is_audible_(is_audible), |
| 308 is_visible_(is_visible), | 312 is_visible_(is_visible), |
| 309 is_loaded_(false), | 313 is_loaded_(false), |
| 310 is_paused_(false), | 314 is_paused_(false), |
| 311 has_body_(false), | 315 has_body_(false), |
| 312 using_spdy_proxy_(false), | 316 using_spdy_proxy_(false), |
| 313 load_started_time_(base::TimeTicks::Now()), | 317 load_started_time_(base::TimeTicks::Now()), |
| 314 scheduler_(scheduler), | 318 scheduler_(scheduler), |
| 315 in_flight_delayable_count_(0), | 319 in_flight_delayable_count_(0), |
| 316 total_layout_blocking_count_(0), | 320 total_layout_blocking_count_(0), |
| 317 throttle_state_(ResourceScheduler::THROTTLED) {} | 321 throttle_state_(ResourceScheduler::THROTTLED), |
| 322 fetch_mode_(0) { | |
| 323 std::string fetch_mode_cmd = | |
|
Bryan McQuade
2015/07/22 17:46:48
Could we make ResourceScheduler constructor the ca
Pat Meenan
2015/07/28 17:14:21
Done.
| |
| 324 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
| 325 switches::kFetchMode); | |
| 326 if (!fetch_mode_cmd.empty()) { | |
| 327 int temp; | |
| 328 if (base::StringToInt(fetch_mode_cmd, &temp)) | |
| 329 fetch_mode_ = temp; | |
| 330 } | |
| 331 } | |
| 318 | 332 |
| 319 ~Client() { | 333 ~Client() { |
| 320 // Update to default state and pause to ensure the scheduler has a | 334 // Update to default state and pause to ensure the scheduler has a |
| 321 // correct count of relevant types of clients. | 335 // correct count of relevant types of clients. |
| 322 is_visible_ = false; | 336 is_visible_ = false; |
| 323 is_audible_ = false; | 337 is_audible_ = false; |
| 324 is_paused_ = true; | 338 is_paused_ = true; |
| 325 UpdateThrottleState(); | 339 UpdateThrottleState(); |
| 326 } | 340 } |
| 327 | 341 |
| 328 void ScheduleRequest( | 342 void ScheduleRequest( |
| 329 net::URLRequest* url_request, | 343 net::URLRequest* url_request, |
| 330 ScheduledResourceRequest* request) { | 344 ScheduledResourceRequest* request) { |
| 345 /* | |
| 346 char buff[20]; | |
| 347 wsprintfA(buff, "[%d] - ", request->get_request_priority_params().priority); | |
| 348 OutputDebugStringA(std::string(std::string(buff) + request->url_request()->u rl().spec()).c_str()); | |
| 349 */ | |
| 331 if (ShouldStartRequest(request) == START_REQUEST) | 350 if (ShouldStartRequest(request) == START_REQUEST) |
| 332 StartRequest(request); | 351 StartRequest(request); |
| 333 else | 352 else |
| 334 pending_requests_.Insert(request); | 353 pending_requests_.Insert(request); |
| 335 SetRequestClassification(request, ClassifyRequest(request)); | 354 SetRequestClassification(request, ClassifyRequest(request)); |
| 336 } | 355 } |
| 337 | 356 |
| 338 void RemoveRequest(ScheduledResourceRequest* request) { | 357 void RemoveRequest(ScheduledResourceRequest* request) { |
| 339 if (pending_requests_.IsQueued(request)) { | 358 if (pending_requests_.IsQueued(request)) { |
| 340 pending_requests_.Erase(request); | 359 pending_requests_.Erase(request); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 468 scheduler_->DecrementCoalescedClients(); | 487 scheduler_->DecrementCoalescedClients(); |
| 469 } | 488 } |
| 470 } | 489 } |
| 471 | 490 |
| 472 void OnNavigate() { | 491 void OnNavigate() { |
| 473 has_body_ = false; | 492 has_body_ = false; |
| 474 is_loaded_ = false; | 493 is_loaded_ = false; |
| 475 } | 494 } |
| 476 | 495 |
| 477 void OnWillInsertBody() { | 496 void OnWillInsertBody() { |
| 497 // OutputDebugStringA("************ Inserted Body"); | |
| 478 has_body_ = true; | 498 has_body_ = true; |
| 479 LoadAnyStartablePendingRequests(); | 499 LoadAnyStartablePendingRequests(); |
| 480 } | 500 } |
| 481 | 501 |
| 482 void OnReceivedSpdyProxiedHttpResponse() { | 502 void OnReceivedSpdyProxiedHttpResponse() { |
| 483 if (!using_spdy_proxy_) { | 503 if (!using_spdy_proxy_) { |
| 484 using_spdy_proxy_ = true; | 504 using_spdy_proxy_ = true; |
| 485 LoadAnyStartablePendingRequests(); | 505 LoadAnyStartablePendingRequests(); |
| 486 } | 506 } |
| 487 } | 507 } |
| 488 | 508 |
| 489 void ReprioritizeRequest(ScheduledResourceRequest* request, | 509 void ReprioritizeRequest(ScheduledResourceRequest* request, |
| 490 RequestPriorityParams old_priority_params, | 510 RequestPriorityParams old_priority_params, |
| 491 RequestPriorityParams new_priority_params) { | 511 RequestPriorityParams new_priority_params) { |
| 492 request->url_request()->SetPriority(new_priority_params.priority); | 512 request->url_request()->SetPriority(new_priority_params.priority); |
| 493 request->set_request_priority_params(new_priority_params); | 513 request->set_request_priority_params(new_priority_params); |
| 514 /* | |
| 515 char buff[30]; | |
| 516 wsprintfA(buff, "[%d -> %d] - ", old_priority_params.priority, new_priority_ params.priority); | |
| 517 OutputDebugStringA(std::string(std::string(buff) + request->url_request()->u rl().spec()).c_str()); | |
| 518 */ | |
| 494 if (!pending_requests_.IsQueued(request)) { | 519 if (!pending_requests_.IsQueued(request)) { |
| 495 DCHECK(ContainsKey(in_flight_requests_, request)); | 520 DCHECK(ContainsKey(in_flight_requests_, request)); |
| 496 // The priority of the request and priority support of the server may | 521 // The priority of the request and priority support of the server may |
| 497 // have changed, so update the delayable count. | 522 // have changed, so update the delayable count. |
| 498 SetRequestClassification(request, ClassifyRequest(request)); | 523 SetRequestClassification(request, ClassifyRequest(request)); |
| 499 // Request has already started. | 524 // Request has already started. |
| 500 return; | 525 return; |
| 501 } | 526 } |
| 502 | 527 |
| 503 pending_requests_.Erase(request); | 528 pending_requests_.Erase(request); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 617 DCHECK_EQ( | 642 DCHECK_EQ( |
| 618 CountRequestsWithClassification(IN_FLIGHT_DELAYABLE_REQUEST, false), | 643 CountRequestsWithClassification(IN_FLIGHT_DELAYABLE_REQUEST, false), |
| 619 in_flight_delayable_count_); | 644 in_flight_delayable_count_); |
| 620 DCHECK_EQ(CountRequestsWithClassification(LAYOUT_BLOCKING_REQUEST, true), | 645 DCHECK_EQ(CountRequestsWithClassification(LAYOUT_BLOCKING_REQUEST, true), |
| 621 total_layout_blocking_count_); | 646 total_layout_blocking_count_); |
| 622 } | 647 } |
| 623 | 648 |
| 624 RequestClassification ClassifyRequest(ScheduledResourceRequest* request) { | 649 RequestClassification ClassifyRequest(ScheduledResourceRequest* request) { |
| 625 // If a request is already marked as layout-blocking make sure to keep the | 650 // If a request is already marked as layout-blocking make sure to keep the |
| 626 // classification across redirects unless the priority was lowered. | 651 // classification across redirects unless the priority was lowered. |
| 627 if (request->classification() == LAYOUT_BLOCKING_REQUEST && | 652 if (fetch_mode_ == 2) { |
| 628 request->url_request()->priority() > net::LOW) { | 653 if (request->classification() == LAYOUT_BLOCKING_REQUEST && |
| 629 return LAYOUT_BLOCKING_REQUEST; | 654 request->url_request()->priority() > net::MEDIUM) { |
| 630 } | 655 return LAYOUT_BLOCKING_REQUEST; |
| 656 } | |
| 631 | 657 |
| 632 if (!has_body_ && request->url_request()->priority() > net::LOW) | 658 if (!has_body_ && request->url_request()->priority() > net::MEDIUM) |
| 633 return LAYOUT_BLOCKING_REQUEST; | 659 return LAYOUT_BLOCKING_REQUEST; |
| 634 | 660 |
| 635 if (request->url_request()->priority() < net::LOW) { | 661 if (request->url_request()->priority() < net::MEDIUM) { |
| 636 net::HostPortPair host_port_pair = | 662 net::HostPortPair host_port_pair = |
| 637 net::HostPortPair::FromURL(request->url_request()->url()); | 663 net::HostPortPair::FromURL(request->url_request()->url()); |
| 638 net::HttpServerProperties& http_server_properties = | 664 net::HttpServerProperties& http_server_properties = |
| 639 *request->url_request()->context()->http_server_properties(); | 665 *request->url_request()->context()->http_server_properties(); |
| 640 if (!http_server_properties.SupportsRequestPriority(host_port_pair) && | 666 if (!http_server_properties.SupportsRequestPriority(host_port_pair) && |
| 641 ContainsKey(in_flight_requests_, request)) { | 667 ContainsKey(in_flight_requests_, request)) { |
| 642 return IN_FLIGHT_DELAYABLE_REQUEST; | 668 return IN_FLIGHT_DELAYABLE_REQUEST; |
| 669 } | |
| 670 } | |
| 671 } else { | |
| 672 if (request->classification() == LAYOUT_BLOCKING_REQUEST && | |
| 673 request->url_request()->priority() > net::LOW) { | |
| 674 return LAYOUT_BLOCKING_REQUEST; | |
| 675 } | |
| 676 | |
| 677 if (!has_body_ && request->url_request()->priority() > net::LOW) | |
| 678 return LAYOUT_BLOCKING_REQUEST; | |
| 679 | |
| 680 if (request->url_request()->priority() < net::LOW) { | |
| 681 net::HostPortPair host_port_pair = | |
| 682 net::HostPortPair::FromURL(request->url_request()->url()); | |
| 683 net::HttpServerProperties& http_server_properties = | |
| 684 *request->url_request()->context()->http_server_properties(); | |
| 685 if (!http_server_properties.SupportsRequestPriority(host_port_pair) && | |
| 686 ContainsKey(in_flight_requests_, request)) { | |
| 687 return IN_FLIGHT_DELAYABLE_REQUEST; | |
| 688 } | |
| 643 } | 689 } |
| 644 } | 690 } |
| 645 return NORMAL_REQUEST; | 691 return NORMAL_REQUEST; |
| 646 } | 692 } |
| 647 | 693 |
| 648 bool ShouldKeepSearching( | 694 bool ShouldKeepSearching( |
| 649 const net::HostPortPair& active_request_host) const { | 695 const net::HostPortPair& active_request_host) const { |
| 650 size_t same_host_count = 0; | 696 size_t same_host_count = 0; |
| 651 for (RequestSet::const_iterator it = in_flight_requests_.begin(); | 697 for (RequestSet::const_iterator it = in_flight_requests_.begin(); |
| 652 it != in_flight_requests_.end(); ++it) { | 698 it != in_flight_requests_.end(); ++it) { |
| 653 net::HostPortPair host_port_pair = | 699 net::HostPortPair host_port_pair = |
| 654 net::HostPortPair::FromURL((*it)->url_request()->url()); | 700 net::HostPortPair::FromURL((*it)->url_request()->url()); |
| 655 if (active_request_host.Equals(host_port_pair)) { | 701 if (active_request_host.Equals(host_port_pair)) { |
| 656 same_host_count++; | 702 same_host_count++; |
| 657 if (same_host_count >= kMaxNumDelayableRequestsPerHost) | 703 if (same_host_count >= kMaxNumDelayableRequestsPerHost) |
| 658 return true; | 704 return true; |
| 659 } | 705 } |
| 660 } | 706 } |
| 661 return false; | 707 return false; |
| 662 } | 708 } |
| 663 | 709 |
| 664 void StartRequest(ScheduledResourceRequest* request) { | 710 void StartRequest(ScheduledResourceRequest* request) { |
| 665 InsertInFlightRequest(request); | 711 InsertInFlightRequest(request); |
| 712 /* | |
| 713 size_t counts[5]; | |
| 714 memset(&counts, 0, sizeof(counts)); | |
| 715 // count the in-flight requests at each priority level | |
| 716 for (RequestSet::const_iterator it = in_flight_requests_.begin(); | |
| 717 it != in_flight_requests_.end(); ++it) { | |
| 718 int priority = (*it)->get_request_priority_params().priority; | |
| 719 if (priority >= 0 && priority <= 4) { | |
| 720 counts[priority]++; | |
| 721 } | |
| 722 } | |
| 723 char buff[80]; | |
| 724 wsprintfA(buff, "Starting [%d] - %s{%d:%d:%d:%d:%d}%s - ", request->get_requ est_priority_params().priority, has_body_ ? "" : "*", counts[0], counts[1], coun ts[2], counts[3], counts[4], has_body_ ? "" : "*"); | |
| 725 OutputDebugStringA(std::string(std::string(buff) + request->url_request()->u rl().spec()).c_str()); | |
| 726 */ | |
| 666 request->Start(); | 727 request->Start(); |
| 667 } | 728 } |
| 668 | 729 |
| 669 // ShouldStartRequest is the main scheduling algorithm. | 730 // ShouldStartRequest is the main scheduling algorithm. |
| 670 // | 731 // |
| 671 // Requests are evaluated on five attributes: | 732 // Requests are evaluated on five attributes: |
| 672 // | 733 // |
| 673 // 1. Non-delayable requests: | 734 // 1. Non-delayable requests: |
| 674 // * Synchronous requests. | 735 // * Synchronous requests. |
| 675 // * Non-HTTP[S] requests. | 736 // * Non-HTTP[S] requests. |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 762 } | 823 } |
| 763 | 824 |
| 764 if (throttle_state_ == THROTTLED && | 825 if (throttle_state_ == THROTTLED && |
| 765 in_flight_requests_.size() >= kMaxNumThrottledRequestsPerClient) { | 826 in_flight_requests_.size() >= kMaxNumThrottledRequestsPerClient) { |
| 766 // There may still be request-priority-capable requests that should be | 827 // There may still be request-priority-capable requests that should be |
| 767 // issued. | 828 // issued. |
| 768 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; | 829 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; |
| 769 } | 830 } |
| 770 | 831 |
| 771 // High-priority and layout-blocking requests. | 832 // High-priority and layout-blocking requests. |
| 772 if (url_request.priority() >= net::LOW) { | 833 if (fetch_mode_ == 2) { |
| 773 return START_REQUEST; | 834 if (url_request.priority() >= net::MEDIUM) { |
| 835 return START_REQUEST; | |
| 836 } | |
| 837 } else { | |
| 838 if (url_request.priority() >= net::LOW) { | |
| 839 return START_REQUEST; | |
| 840 } | |
| 774 } | 841 } |
| 775 | 842 |
| 776 if (in_flight_delayable_count_ >= kMaxNumDelayableRequestsPerClient) { | 843 if (in_flight_delayable_count_ >= kMaxNumDelayableRequestsPerClient) { |
| 777 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; | 844 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
| 778 } | 845 } |
| 779 | 846 |
| 780 if (ShouldKeepSearching(host_port_pair)) { | 847 if (ShouldKeepSearching(host_port_pair)) { |
| 781 // There may be other requests for other hosts we'd allow, | 848 // There may be other requests for other hosts we'd allow, |
| 782 // so keep checking. | 849 // so keep checking. |
| 783 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; | 850 return DO_NOT_START_REQUEST_AND_KEEP_SEARCHING; |
| 784 } | 851 } |
| 785 | 852 |
| 786 bool have_immediate_requests_in_flight = | 853 if (fetch_mode_ == 2) { |
| 787 in_flight_requests_.size() > in_flight_delayable_count_; | 854 // If we are in render-blocking more make sure at least 2 requests |
| 788 if (have_immediate_requests_in_flight && | 855 // are in-flight. High priority requests would have alreay |
| 789 (!has_body_ || total_layout_blocking_count_ != 0) && | 856 // been allowed so this just restricts low-priority requests. |
| 790 // Do not allow a low priority request through in parallel if | 857 if ((!has_body_ || total_layout_blocking_count_ != 0) && |
| 791 // we are in a limit field trial. | 858 in_flight_requests_.size() >= 2) { |
| 792 (scheduler_->limit_outstanding_requests() || | 859 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; |
| 793 in_flight_delayable_count_ != 0)) { | 860 } |
| 794 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; | 861 |
| 862 // only allow 1 lower priority resource while 1 higher priority resource i s pending | |
| 863 size_t higher_priority = 0; | |
| 864 size_t equal_priority = 0; | |
| 865 net::RequestPriority priority = url_request.priority(); | |
| 866 for (RequestSet::const_iterator it = in_flight_requests_.begin(); | |
| 867 it != in_flight_requests_.end(); ++it) { | |
| 868 net::RequestPriority pending_priority = (*it)->get_request_priority_para ms().priority; | |
| 869 if (pending_priority > priority) { | |
| 870 higher_priority++; | |
| 871 } else if (pending_priority == priority) { | |
| 872 equal_priority++; | |
| 873 } | |
| 874 } | |
| 875 if (higher_priority > 1 || (higher_priority == 1 && equal_priority > 0)) { | |
| 876 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; | |
| 877 } | |
| 878 | |
| 879 } else { | |
| 880 bool have_immediate_requests_in_flight = | |
| 881 in_flight_requests_.size() > in_flight_delayable_count_; | |
| 882 if (have_immediate_requests_in_flight && | |
| 883 (!has_body_ || total_layout_blocking_count_ != 0) && | |
| 884 // Do not allow a low priority request through in parallel if | |
| 885 // we are in a limit field trial. | |
| 886 (scheduler_->limit_outstanding_requests() || | |
| 887 in_flight_delayable_count_ != 0)) { | |
| 888 return DO_NOT_START_REQUEST_AND_STOP_SEARCHING; | |
| 889 } | |
| 795 } | 890 } |
| 796 | 891 |
| 797 return START_REQUEST; | 892 return START_REQUEST; |
| 798 } | 893 } |
| 799 | 894 |
| 800 void LoadAnyStartablePendingRequests() { | 895 void LoadAnyStartablePendingRequests() { |
| 801 // We iterate through all the pending requests, starting with the highest | 896 // We iterate through all the pending requests, starting with the highest |
| 802 // priority one. For each entry, one of three things can happen: | 897 // priority one. For each entry, one of three things can happen: |
| 803 // 1) We start the request, remove it from the list, and keep checking. | 898 // 1) We start the request, remove it from the list, and keep checking. |
| 804 // 2) We do NOT start the request, but ShouldStartRequest() signals us that | 899 // 2) We do NOT start the request, but ShouldStartRequest() signals us that |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 844 RequestSet in_flight_requests_; | 939 RequestSet in_flight_requests_; |
| 845 base::TimeTicks load_started_time_; | 940 base::TimeTicks load_started_time_; |
| 846 // The last time the client switched state between active and background. | 941 // The last time the client switched state between active and background. |
| 847 base::TimeTicks last_active_switch_time_; | 942 base::TimeTicks last_active_switch_time_; |
| 848 ResourceScheduler* scheduler_; | 943 ResourceScheduler* scheduler_; |
| 849 // The number of delayable in-flight requests. | 944 // The number of delayable in-flight requests. |
| 850 size_t in_flight_delayable_count_; | 945 size_t in_flight_delayable_count_; |
| 851 // The number of layout-blocking in-flight requests. | 946 // The number of layout-blocking in-flight requests. |
| 852 size_t total_layout_blocking_count_; | 947 size_t total_layout_blocking_count_; |
| 853 ResourceScheduler::ClientThrottleState throttle_state_; | 948 ResourceScheduler::ClientThrottleState throttle_state_; |
| 949 int fetch_mode_; | |
| 854 }; | 950 }; |
| 855 | 951 |
| 856 ResourceScheduler::ResourceScheduler() | 952 ResourceScheduler::ResourceScheduler() |
| 857 : should_coalesce_(false), | 953 : should_coalesce_(false), |
| 858 should_throttle_(false), | 954 should_throttle_(false), |
| 859 active_clients_loading_(0), | 955 active_clients_loading_(0), |
| 860 coalesced_clients_(0), | 956 coalesced_clients_(0), |
| 861 limit_outstanding_requests_(false), | 957 limit_outstanding_requests_(false), |
| 862 outstanding_request_limit_(0), | 958 outstanding_request_limit_(0), |
| 959 fetch_mode_(0), | |
| 863 coalescing_timer_(new base::Timer(true /* retain_user_task */, | 960 coalescing_timer_(new base::Timer(true /* retain_user_task */, |
| 864 true /* is_repeating */)) { | 961 true /* is_repeating */)) { |
| 865 std::string throttling_trial_group = | 962 std::string throttling_trial_group = |
| 866 base::FieldTrialList::FindFullName(kThrottleCoalesceFieldTrial); | 963 base::FieldTrialList::FindFullName(kThrottleCoalesceFieldTrial); |
| 867 if (throttling_trial_group == kThrottleCoalesceFieldTrialThrottle) { | 964 if (throttling_trial_group == kThrottleCoalesceFieldTrialThrottle) { |
| 868 should_throttle_ = true; | 965 should_throttle_ = true; |
| 869 } else if (throttling_trial_group == kThrottleCoalesceFieldTrialCoalesce) { | 966 } else if (throttling_trial_group == kThrottleCoalesceFieldTrialCoalesce) { |
| 870 should_coalesce_ = true; | 967 should_coalesce_ = true; |
| 871 should_throttle_ = true; | 968 should_throttle_ = true; |
| 872 } | 969 } |
| 873 | 970 |
| 874 std::string outstanding_limit_trial_group = | 971 std::string outstanding_limit_trial_group = |
| 875 base::FieldTrialList::FindFullName(kRequestLimitFieldTrial); | 972 base::FieldTrialList::FindFullName(kRequestLimitFieldTrial); |
| 876 std::vector<std::string> split_group( | 973 std::vector<std::string> split_group( |
| 877 base::SplitString(outstanding_limit_trial_group, "=", | 974 base::SplitString(outstanding_limit_trial_group, "=", |
| 878 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL)); | 975 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL)); |
| 879 int outstanding_limit = 0; | 976 int outstanding_limit = 0; |
| 880 if (split_group.size() == 2 && | 977 if (split_group.size() == 2 && |
| 881 split_group[0] == kRequestLimitFieldTrialGroupPrefix && | 978 split_group[0] == kRequestLimitFieldTrialGroupPrefix && |
| 882 base::StringToInt(split_group[1], &outstanding_limit) && | 979 base::StringToInt(split_group[1], &outstanding_limit) && |
| 883 outstanding_limit > 0) { | 980 outstanding_limit > 0) { |
| 884 limit_outstanding_requests_ = true; | 981 limit_outstanding_requests_ = true; |
| 885 outstanding_request_limit_ = outstanding_limit; | 982 outstanding_request_limit_ = outstanding_limit; |
| 886 } | 983 } |
| 984 | |
| 985 std::string fetch_mode_cmd = | |
| 986 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
| 987 switches::kFetchMode); | |
| 988 if (!fetch_mode_cmd.empty()) { | |
| 989 int temp; | |
| 990 if (base::StringToInt(fetch_mode_cmd, &temp)) | |
| 991 fetch_mode_ = temp; | |
| 992 } | |
| 887 } | 993 } |
| 888 | 994 |
| 889 ResourceScheduler::~ResourceScheduler() { | 995 ResourceScheduler::~ResourceScheduler() { |
| 890 DCHECK(unowned_requests_.empty()); | 996 DCHECK(unowned_requests_.empty()); |
| 891 DCHECK(client_map_.empty()); | 997 DCHECK(client_map_.empty()); |
| 892 } | 998 } |
| 893 | 999 |
| 894 void ResourceScheduler::SetThrottleOptionsForTesting(bool should_throttle, | 1000 void ResourceScheduler::SetThrottleOptionsForTesting(bool should_throttle, |
| 895 bool should_coalesce) { | 1001 bool should_coalesce) { |
| 896 should_coalesce_ = should_coalesce; | 1002 should_coalesce_ = should_coalesce; |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1180 NOTREACHED(); | 1286 NOTREACHED(); |
| 1181 return; | 1287 return; |
| 1182 } | 1288 } |
| 1183 RequestPriorityParams new_priority_params(new_priority, | 1289 RequestPriorityParams new_priority_params(new_priority, |
| 1184 new_intra_priority_value); | 1290 new_intra_priority_value); |
| 1185 RequestPriorityParams old_priority_params = | 1291 RequestPriorityParams old_priority_params = |
| 1186 request->get_request_priority_params(); | 1292 request->get_request_priority_params(); |
| 1187 | 1293 |
| 1188 DCHECK(old_priority_params != new_priority_params); | 1294 DCHECK(old_priority_params != new_priority_params); |
| 1189 | 1295 |
| 1296 // only allow priority promotions | |
| 1297 if (fetch_mode_ == 2 && old_priority_params.GreaterThan(new_priority_params)) | |
| 1298 return; | |
| 1299 | |
| 1190 ClientMap::iterator client_it = client_map_.find(request->client_id()); | 1300 ClientMap::iterator client_it = client_map_.find(request->client_id()); |
| 1191 if (client_it == client_map_.end()) { | 1301 if (client_it == client_map_.end()) { |
| 1192 // The client was likely deleted shortly before we received this IPC. | 1302 // The client was likely deleted shortly before we received this IPC. |
| 1193 request->url_request()->SetPriority(new_priority_params.priority); | 1303 request->url_request()->SetPriority(new_priority_params.priority); |
| 1194 request->set_request_priority_params(new_priority_params); | 1304 request->set_request_priority_params(new_priority_params); |
| 1195 return; | 1305 return; |
| 1196 } | 1306 } |
| 1197 | 1307 |
| 1198 if (old_priority_params == new_priority_params) | 1308 if (old_priority_params == new_priority_params) |
| 1199 return; | 1309 return; |
| 1200 | 1310 |
| 1201 Client *client = client_it->second; | 1311 Client *client = client_it->second; |
| 1202 client->ReprioritizeRequest( | 1312 client->ReprioritizeRequest( |
| 1203 request, old_priority_params, new_priority_params); | 1313 request, old_priority_params, new_priority_params); |
| 1204 } | 1314 } |
| 1205 | 1315 |
| 1206 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( | 1316 ResourceScheduler::ClientId ResourceScheduler::MakeClientId( |
| 1207 int child_id, int route_id) { | 1317 int child_id, int route_id) { |
| 1208 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; | 1318 return (static_cast<ResourceScheduler::ClientId>(child_id) << 32) | route_id; |
| 1209 } | 1319 } |
| 1210 | 1320 |
| 1211 } // namespace content | 1321 } // namespace content |
| OLD | NEW |