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 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading | 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading |
| 6 | 6 |
| 7 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 7 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| 8 | 8 |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 | 10 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 #include "content/browser/service_worker/service_worker_navigation_handle_core.h " | 71 #include "content/browser/service_worker/service_worker_navigation_handle_core.h " |
| 72 #include "content/browser/service_worker/service_worker_request_handler.h" | 72 #include "content/browser/service_worker/service_worker_request_handler.h" |
| 73 #include "content/browser/streams/stream.h" | 73 #include "content/browser/streams/stream.h" |
| 74 #include "content/browser/streams/stream_context.h" | 74 #include "content/browser/streams/stream_context.h" |
| 75 #include "content/browser/streams/stream_registry.h" | 75 #include "content/browser/streams/stream_registry.h" |
| 76 #include "content/common/net/url_request_service_worker_data.h" | 76 #include "content/common/net/url_request_service_worker_data.h" |
| 77 #include "content/common/resource_messages.h" | 77 #include "content/common/resource_messages.h" |
| 78 #include "content/common/resource_request.h" | 78 #include "content/common/resource_request.h" |
| 79 #include "content/common/resource_request_body_impl.h" | 79 #include "content/common/resource_request_body_impl.h" |
| 80 #include "content/common/resource_request_completion_status.h" | 80 #include "content/common/resource_request_completion_status.h" |
| 81 #include "content/common/site_isolation_policy.h" | |
| 81 #include "content/common/view_messages.h" | 82 #include "content/common/view_messages.h" |
| 82 #include "content/public/browser/browser_thread.h" | 83 #include "content/public/browser/browser_thread.h" |
| 83 #include "content/public/browser/global_request_id.h" | 84 #include "content/public/browser/global_request_id.h" |
| 84 #include "content/public/browser/navigation_ui_data.h" | 85 #include "content/public/browser/navigation_ui_data.h" |
| 85 #include "content/public/browser/plugin_service.h" | 86 #include "content/public/browser/plugin_service.h" |
| 86 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 87 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
| 87 #include "content/public/browser/resource_request_details.h" | 88 #include "content/public/browser/resource_request_details.h" |
| 88 #include "content/public/browser/resource_throttle.h" | 89 #include "content/public/browser/resource_throttle.h" |
| 89 #include "content/public/browser/stream_handle.h" | 90 #include "content/public/browser/stream_handle.h" |
| 90 #include "content/public/browser/stream_info.h" | 91 #include "content/public/browser/stream_info.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 | 162 |
| 162 namespace content { | 163 namespace content { |
| 163 | 164 |
| 164 namespace { | 165 namespace { |
| 165 | 166 |
| 166 static ResourceDispatcherHostImpl* g_resource_dispatcher_host; | 167 static ResourceDispatcherHostImpl* g_resource_dispatcher_host; |
| 167 | 168 |
| 168 // The interval for calls to ResourceDispatcherHostImpl::UpdateLoadStates | 169 // The interval for calls to ResourceDispatcherHostImpl::UpdateLoadStates |
| 169 const int kUpdateLoadStatesIntervalMsec = 250; | 170 const int kUpdateLoadStatesIntervalMsec = 250; |
| 170 | 171 |
| 172 // The interval for calls to RecordOutstandingRequestsStats. | |
| 173 const int kRecordOutstandingRequestsStatsIntervalMsec = 60000; | |
|
kinuko
2017/06/23 04:35:06
nit: maybe use Sec rather than Msec (and TimeDelta
Kunihiko Sakamoto
2017/06/23 09:08:10
Done.
| |
| 174 | |
| 171 // Maximum byte "cost" of all the outstanding requests for a renderer. | 175 // Maximum byte "cost" of all the outstanding requests for a renderer. |
| 172 // See declaration of |max_outstanding_requests_cost_per_process_| for details. | 176 // See declaration of |max_outstanding_requests_cost_per_process_| for details. |
| 173 // This bound is 25MB, which allows for around 6000 outstanding requests. | 177 // This bound is 25MB, which allows for around 6000 outstanding requests. |
| 174 const int kMaxOutstandingRequestsCostPerProcess = 26214400; | 178 const int kMaxOutstandingRequestsCostPerProcess = 26214400; |
| 175 | 179 |
| 176 // The number of milliseconds after noting a user gesture that we will | 180 // The number of milliseconds after noting a user gesture that we will |
| 177 // tag newly-created URLRequest objects with the | 181 // tag newly-created URLRequest objects with the |
| 178 // net::LOAD_MAYBE_USER_GESTURE load flag. This is a fairly arbitrary | 182 // net::LOAD_MAYBE_USER_GESTURE load flag. This is a fairly arbitrary |
| 179 // guess at how long to expect direct impact from a user gesture, but | 183 // guess at how long to expect direct impact from a user gesture, but |
| 180 // this should be OK as the load flag is a best-effort thing only, | 184 // this should be OK as the load flag is a best-effort thing only, |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 353 g_resource_dispatcher_host = this; | 357 g_resource_dispatcher_host = this; |
| 354 | 358 |
| 355 ANNOTATE_BENIGN_RACE( | 359 ANNOTATE_BENIGN_RACE( |
| 356 &last_user_gesture_time_, | 360 &last_user_gesture_time_, |
| 357 "We don't care about the precise value, see http://crbug.com/92889"); | 361 "We don't care about the precise value, see http://crbug.com/92889"); |
| 358 | 362 |
| 359 io_thread_task_runner_->PostTask( | 363 io_thread_task_runner_->PostTask( |
| 360 FROM_HERE, | 364 FROM_HERE, |
| 361 base::Bind(&ResourceDispatcherHostImpl::OnInit, base::Unretained(this))); | 365 base::Bind(&ResourceDispatcherHostImpl::OnInit, base::Unretained(this))); |
| 362 | 366 |
| 363 update_load_states_timer_.reset(new base::RepeatingTimer()); | 367 update_load_states_timer_ = base::MakeUnique<base::RepeatingTimer>(); |
| 368 | |
| 369 // Monitor per-tab outstanding requests only if OOPIF is not enabled, because | |
| 370 // the routing id doesn't represent tabs in OOPIF modes. | |
| 371 if (!SiteIsolationPolicy::UseDedicatedProcessesForAllSites() && | |
| 372 !SiteIsolationPolicy::IsTopDocumentIsolationEnabled() && | |
| 373 !SiteIsolationPolicy::AreIsolatedOriginsEnabled()) { | |
| 374 record_outstanding_requests_stats_timer_ = | |
| 375 base::MakeUnique<base::RepeatingTimer>(); | |
| 376 } | |
| 364 } | 377 } |
| 365 | 378 |
| 366 // The default ctor is only used by unittests. It is reasonable to assume that | 379 // The default ctor is only used by unittests. It is reasonable to assume that |
| 367 // the main thread and the IO thread are the same for unittests. | 380 // the main thread and the IO thread are the same for unittests. |
| 368 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() | 381 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() |
| 369 : ResourceDispatcherHostImpl(CreateDownloadHandlerIntercept(), | 382 : ResourceDispatcherHostImpl(CreateDownloadHandlerIntercept(), |
| 370 base::ThreadTaskRunnerHandle::Get()) {} | 383 base::ThreadTaskRunnerHandle::Get()) {} |
| 371 | 384 |
| 372 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { | 385 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { |
| 373 DCHECK(outstanding_requests_stats_map_.empty()); | 386 DCHECK(outstanding_requests_stats_map_.empty()); |
| 387 DCHECK(outstanding_requests_per_tab_map_.empty()); | |
| 374 DCHECK(g_resource_dispatcher_host); | 388 DCHECK(g_resource_dispatcher_host); |
| 375 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); | 389 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); |
| 376 g_resource_dispatcher_host = NULL; | 390 g_resource_dispatcher_host = NULL; |
| 377 } | 391 } |
| 378 | 392 |
| 379 // static | 393 // static |
| 380 ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() { | 394 ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() { |
| 381 return g_resource_dispatcher_host; | 395 return g_resource_dispatcher_host; |
| 382 } | 396 } |
| 383 | 397 |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 582 | 596 |
| 583 const net::URLRequestJobFactory* job_factory = | 597 const net::URLRequestJobFactory* job_factory = |
| 584 info->GetContext()->GetRequestContext()->job_factory(); | 598 info->GetContext()->GetRequestContext()->job_factory(); |
| 585 if (!url.is_valid() || job_factory->IsHandledProtocol(url.scheme())) | 599 if (!url.is_valid() || job_factory->IsHandledProtocol(url.scheme())) |
| 586 return false; | 600 return false; |
| 587 | 601 |
| 588 return delegate_->HandleExternalProtocol(url, info); | 602 return delegate_->HandleExternalProtocol(url, info); |
| 589 } | 603 } |
| 590 | 604 |
| 591 void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) { | 605 void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) { |
| 592 // Make sure we have the load state monitor running. | 606 // Make sure we have the load state monitors running. |
| 593 if (!update_load_states_timer_->IsRunning() && | 607 if (!update_load_states_timer_->IsRunning() && |
| 594 scheduler_->HasLoadingClients()) { | 608 scheduler_->HasLoadingClients()) { |
| 595 update_load_states_timer_->Start( | 609 update_load_states_timer_->Start( |
| 596 FROM_HERE, TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec), | 610 FROM_HERE, TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec), |
| 597 this, &ResourceDispatcherHostImpl::UpdateLoadInfo); | 611 this, &ResourceDispatcherHostImpl::UpdateLoadInfo); |
| 598 } | 612 } |
| 613 if (record_outstanding_requests_stats_timer_ && | |
| 614 !record_outstanding_requests_stats_timer_->IsRunning()) { | |
| 615 record_outstanding_requests_stats_timer_->Start( | |
| 616 FROM_HERE, | |
| 617 TimeDelta::FromMilliseconds( | |
| 618 kRecordOutstandingRequestsStatsIntervalMsec), | |
| 619 this, &ResourceDispatcherHostImpl::RecordOutstandingRequestsStats); | |
| 620 } | |
| 599 } | 621 } |
| 600 | 622 |
| 601 void ResourceDispatcherHostImpl::DidReceiveRedirect( | 623 void ResourceDispatcherHostImpl::DidReceiveRedirect( |
| 602 ResourceLoader* loader, | 624 ResourceLoader* loader, |
| 603 const GURL& new_url, | 625 const GURL& new_url, |
| 604 ResourceResponse* response) { | 626 ResourceResponse* response) { |
| 605 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); | 627 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); |
| 606 if (delegate_) { | 628 if (delegate_) { |
| 607 delegate_->OnRequestRedirected( | 629 delegate_->OnRequestRedirected( |
| 608 new_url, loader->request(), info->GetContext(), response); | 630 new_url, loader->request(), info->GetContext(), response); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 777 void ResourceDispatcherHostImpl::OnInit() { | 799 void ResourceDispatcherHostImpl::OnInit() { |
| 778 scheduler_.reset(new ResourceScheduler); | 800 scheduler_.reset(new ResourceScheduler); |
| 779 } | 801 } |
| 780 | 802 |
| 781 void ResourceDispatcherHostImpl::OnShutdown() { | 803 void ResourceDispatcherHostImpl::OnShutdown() { |
| 782 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); | 804 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); |
| 783 | 805 |
| 784 is_shutdown_ = true; | 806 is_shutdown_ = true; |
| 785 pending_loaders_.clear(); | 807 pending_loaders_.clear(); |
| 786 | 808 |
| 787 // Make sure we shutdown the timer now, otherwise by the time our destructor | 809 // Make sure we shutdown the timers now, otherwise by the time our destructor |
| 788 // runs if the timer is still running the Task is deleted twice (once by | 810 // runs if the timer is still running the Task is deleted twice (once by |
| 789 // the MessageLoop and the second time by RepeatingTimer). | 811 // the MessageLoop and the second time by RepeatingTimer). |
| 790 update_load_states_timer_.reset(); | 812 update_load_states_timer_.reset(); |
| 813 record_outstanding_requests_stats_timer_.reset(); | |
| 791 | 814 |
| 792 // Clear blocked requests if any left. | 815 // Clear blocked requests if any left. |
| 793 // Note that we have to do this in 2 passes as we cannot call | 816 // Note that we have to do this in 2 passes as we cannot call |
| 794 // CancelBlockedRequestsForRoute while iterating over | 817 // CancelBlockedRequestsForRoute while iterating over |
| 795 // blocked_loaders_map_, as it modifies it. | 818 // blocked_loaders_map_, as it modifies it. |
| 796 std::set<GlobalFrameRoutingId> ids; | 819 std::set<GlobalFrameRoutingId> ids; |
| 797 for (const auto& blocked_loaders : blocked_loaders_map_) { | 820 for (const auto& blocked_loaders : blocked_loaders_map_) { |
| 798 std::pair<std::set<GlobalFrameRoutingId>::iterator, bool> result = | 821 std::pair<std::set<GlobalFrameRoutingId>::iterator, bool> result = |
| 799 ids.insert(blocked_loaders.first); | 822 ids.insert(blocked_loaders.first); |
| 800 // We should not have duplicates. | 823 // We should not have duplicates. |
| (...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1912 | 1935 |
| 1913 void ResourceDispatcherHostImpl::UpdateOutstandingRequestsStats( | 1936 void ResourceDispatcherHostImpl::UpdateOutstandingRequestsStats( |
| 1914 const ResourceRequestInfoImpl& info, | 1937 const ResourceRequestInfoImpl& info, |
| 1915 const OustandingRequestsStats& stats) { | 1938 const OustandingRequestsStats& stats) { |
| 1916 if (stats.memory_cost == 0 && stats.num_requests == 0) | 1939 if (stats.memory_cost == 0 && stats.num_requests == 0) |
| 1917 outstanding_requests_stats_map_.erase(info.GetChildID()); | 1940 outstanding_requests_stats_map_.erase(info.GetChildID()); |
| 1918 else | 1941 else |
| 1919 outstanding_requests_stats_map_[info.GetChildID()] = stats; | 1942 outstanding_requests_stats_map_[info.GetChildID()] = stats; |
| 1920 } | 1943 } |
| 1921 | 1944 |
| 1945 void ResourceDispatcherHostImpl::IncrementOutstandingRequestsPerTab( | |
| 1946 int count, | |
| 1947 const ResourceRequestInfoImpl& info) { | |
| 1948 auto key = std::make_pair(info.GetChildID(), info.GetRouteID()); | |
| 1949 OutstandingRequestsPerTabMap::iterator entry = | |
| 1950 outstanding_requests_per_tab_map_.insert(std::make_pair(key, 0)).first; | |
| 1951 entry->second += count; | |
| 1952 DCHECK_GE(entry->second, 0); | |
| 1953 if (entry->second == 0) { | |
| 1954 outstanding_requests_per_tab_map_.erase(entry); | |
| 1955 } | |
|
kinuko
2017/06/23 04:35:06
nit: no {} needed for single-line body here and be
Kunihiko Sakamoto
2017/06/23 09:08:10
Done.
| |
| 1956 } | |
| 1957 | |
| 1922 ResourceDispatcherHostImpl::OustandingRequestsStats | 1958 ResourceDispatcherHostImpl::OustandingRequestsStats |
| 1923 ResourceDispatcherHostImpl::IncrementOutstandingRequestsMemory( | 1959 ResourceDispatcherHostImpl::IncrementOutstandingRequestsMemory( |
| 1924 int count, | 1960 int count, |
| 1925 const ResourceRequestInfoImpl& info) { | 1961 const ResourceRequestInfoImpl& info) { |
| 1926 DCHECK_EQ(1, abs(count)); | 1962 DCHECK_EQ(1, abs(count)); |
| 1927 | 1963 |
| 1928 // Retrieve the previous value (defaulting to 0 if not found). | 1964 // Retrieve the previous value (defaulting to 0 if not found). |
| 1929 OustandingRequestsStats stats = GetOutstandingRequestsStats(info); | 1965 OustandingRequestsStats stats = GetOutstandingRequestsStats(info); |
| 1930 | 1966 |
| 1931 // Insert/update the total; delete entries when their count reaches 0. | 1967 // Insert/update the total; delete entries when their count reaches 0. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1947 // in-flight requests for this process, in case we need to transfer it to | 1983 // in-flight requests for this process, in case we need to transfer it to |
| 1948 // another process. This should be a toggle. | 1984 // another process. This should be a toggle. |
| 1949 DCHECK_NE(info->counted_as_in_flight_request(), count > 0); | 1985 DCHECK_NE(info->counted_as_in_flight_request(), count > 0); |
| 1950 info->set_counted_as_in_flight_request(count > 0); | 1986 info->set_counted_as_in_flight_request(count > 0); |
| 1951 | 1987 |
| 1952 OustandingRequestsStats stats = GetOutstandingRequestsStats(*info); | 1988 OustandingRequestsStats stats = GetOutstandingRequestsStats(*info); |
| 1953 stats.num_requests += count; | 1989 stats.num_requests += count; |
| 1954 DCHECK_GE(stats.num_requests, 0); | 1990 DCHECK_GE(stats.num_requests, 0); |
| 1955 UpdateOutstandingRequestsStats(*info, stats); | 1991 UpdateOutstandingRequestsStats(*info, stats); |
| 1956 | 1992 |
| 1993 IncrementOutstandingRequestsPerTab(count, *info); | |
| 1994 | |
| 1957 if (num_in_flight_requests_ > largest_outstanding_request_count_seen_) { | 1995 if (num_in_flight_requests_ > largest_outstanding_request_count_seen_) { |
| 1958 largest_outstanding_request_count_seen_ = num_in_flight_requests_; | 1996 largest_outstanding_request_count_seen_ = num_in_flight_requests_; |
| 1959 UMA_HISTOGRAM_COUNTS_1M( | 1997 UMA_HISTOGRAM_COUNTS_1M( |
| 1960 "Net.ResourceDispatcherHost.OutstandingRequests.Total", | 1998 "Net.ResourceDispatcherHost.OutstandingRequests.Total", |
| 1961 largest_outstanding_request_count_seen_); | 1999 largest_outstanding_request_count_seen_); |
| 1962 } | 2000 } |
| 1963 | 2001 |
| 1964 if (stats.num_requests > | 2002 if (stats.num_requests > |
| 1965 largest_outstanding_request_per_process_count_seen_) { | 2003 largest_outstanding_request_per_process_count_seen_) { |
| 1966 largest_outstanding_request_per_process_count_seen_ = stats.num_requests; | 2004 largest_outstanding_request_per_process_count_seen_ = stats.num_requests; |
| 1967 UMA_HISTOGRAM_COUNTS_1M( | 2005 UMA_HISTOGRAM_COUNTS_1M( |
| 1968 "Net.ResourceDispatcherHost.OutstandingRequests.PerProcess", | 2006 "Net.ResourceDispatcherHost.OutstandingRequests.PerProcess", |
| 1969 largest_outstanding_request_per_process_count_seen_); | 2007 largest_outstanding_request_per_process_count_seen_); |
| 1970 } | 2008 } |
| 1971 | 2009 |
| 2010 if (num_in_flight_requests_ > peak_outstanding_request_count_) { | |
| 2011 peak_outstanding_request_count_ = num_in_flight_requests_; | |
| 2012 } | |
| 2013 | |
| 2014 if (HasRequestsFromMultipleActiveTabs() && | |
| 2015 num_in_flight_requests_ > peak_outstanding_request_count_multitab_) { | |
| 2016 peak_outstanding_request_count_multitab_ = num_in_flight_requests_; | |
| 2017 } | |
| 2018 | |
| 1972 return stats; | 2019 return stats; |
| 1973 } | 2020 } |
| 1974 | 2021 |
| 1975 bool ResourceDispatcherHostImpl::HasSufficientResourcesForRequest( | 2022 bool ResourceDispatcherHostImpl::HasSufficientResourcesForRequest( |
| 1976 net::URLRequest* request) { | 2023 net::URLRequest* request) { |
| 1977 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); | 2024 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); |
| 1978 OustandingRequestsStats stats = IncrementOutstandingRequestsCount(1, info); | 2025 OustandingRequestsStats stats = IncrementOutstandingRequestsCount(1, info); |
| 1979 | 2026 |
| 1980 if (stats.num_requests > max_num_in_flight_requests_per_process_) | 2027 if (stats.num_requests > max_num_in_flight_requests_per_process_) |
| 1981 return false; | 2028 return false; |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2490 // We need to be able to compare all requests to find the most important one | 2537 // We need to be able to compare all requests to find the most important one |
| 2491 // per tab. Since some requests may be navigation requests and we don't have | 2538 // per tab. Since some requests may be navigation requests and we don't have |
| 2492 // their render frame routing IDs yet (which is what we have for subresource | 2539 // their render frame routing IDs yet (which is what we have for subresource |
| 2493 // requests), we must go to the UI thread and compare the requests using their | 2540 // requests), we must go to the UI thread and compare the requests using their |
| 2494 // WebContents. | 2541 // WebContents. |
| 2495 main_thread_task_runner_->PostTask( | 2542 main_thread_task_runner_->PostTask( |
| 2496 FROM_HERE, | 2543 FROM_HERE, |
| 2497 base::Bind(UpdateLoadStateOnUI, loader_delegate_, base::Passed(&infos))); | 2544 base::Bind(UpdateLoadStateOnUI, loader_delegate_, base::Passed(&infos))); |
| 2498 } | 2545 } |
| 2499 | 2546 |
| 2547 void ResourceDispatcherHostImpl::RecordOutstandingRequestsStats() { | |
| 2548 if (peak_outstanding_request_count_ != 0) { | |
| 2549 UMA_HISTOGRAM_COUNTS_1M( | |
| 2550 "Net.ResourceDispatcherHost.PeakOutstandingRequests", | |
| 2551 peak_outstanding_request_count_); | |
| 2552 peak_outstanding_request_count_ = num_in_flight_requests_; | |
| 2553 } | |
| 2554 | |
| 2555 if (peak_outstanding_request_count_multitab_ != 0) { | |
| 2556 UMA_HISTOGRAM_COUNTS_1M( | |
| 2557 "Net.ResourceDispatcherHost.PeakOutstandingRequests.MultiTabLoading", | |
| 2558 peak_outstanding_request_count_multitab_); | |
| 2559 peak_outstanding_request_count_multitab_ = | |
| 2560 HasRequestsFromMultipleActiveTabs() ? num_in_flight_requests_ : 0; | |
| 2561 } | |
| 2562 } | |
| 2563 | |
| 2500 void ResourceDispatcherHostImpl::BlockRequestsForRoute( | 2564 void ResourceDispatcherHostImpl::BlockRequestsForRoute( |
| 2501 const GlobalFrameRoutingId& global_routing_id) { | 2565 const GlobalFrameRoutingId& global_routing_id) { |
| 2502 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); | 2566 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); |
| 2503 DCHECK(blocked_loaders_map_.find(global_routing_id) == | 2567 DCHECK(blocked_loaders_map_.find(global_routing_id) == |
| 2504 blocked_loaders_map_.end()) | 2568 blocked_loaders_map_.end()) |
| 2505 << "BlockRequestsForRoute called multiple time for the same RFH"; | 2569 << "BlockRequestsForRoute called multiple time for the same RFH"; |
| 2506 blocked_loaders_map_[global_routing_id] = | 2570 blocked_loaders_map_[global_routing_id] = |
| 2507 base::MakeUnique<BlockedLoadersList>(); | 2571 base::MakeUnique<BlockedLoadersList>(); |
| 2508 } | 2572 } |
| 2509 | 2573 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2699 is_content_initiated, true, is_new_request, | 2763 is_content_initiated, true, is_new_request, |
| 2700 &throttles); | 2764 &throttles); |
| 2701 if (!throttles.empty()) { | 2765 if (!throttles.empty()) { |
| 2702 handler.reset(new ThrottlingResourceHandler(std::move(handler), request, | 2766 handler.reset(new ThrottlingResourceHandler(std::move(handler), request, |
| 2703 std::move(throttles))); | 2767 std::move(throttles))); |
| 2704 } | 2768 } |
| 2705 } | 2769 } |
| 2706 return handler; | 2770 return handler; |
| 2707 } | 2771 } |
| 2708 | 2772 |
| 2773 bool ResourceDispatcherHostImpl::HasRequestsFromMultipleActiveTabs() { | |
| 2774 if (outstanding_requests_per_tab_map_.size() < 2) | |
| 2775 return false; | |
| 2776 | |
| 2777 int active_tabs = 0; | |
| 2778 for (auto iter = outstanding_requests_per_tab_map_.begin(); | |
| 2779 iter != outstanding_requests_per_tab_map_.end(); ++iter) { | |
| 2780 if (iter->second > 2) { | |
| 2781 active_tabs++; | |
| 2782 if (active_tabs >= 2) { | |
| 2783 return true; | |
| 2784 } | |
| 2785 } | |
| 2786 } | |
| 2787 return false; | |
| 2788 } | |
| 2789 | |
| 2709 } // namespace content | 2790 } // namespace content |
| OLD | NEW |