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 kRecordOutstandingRequestsStatsIntervalSec = 60; | |
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()) { | |
alexmos
2017/06/30 17:27:22
Just saw this CL, and this check seems problematic
| |
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::FromSeconds(kRecordOutstandingRequestsStatsIntervalSec), | |
618 this, &ResourceDispatcherHostImpl::RecordOutstandingRequestsStats); | |
619 } | |
599 } | 620 } |
600 | 621 |
601 void ResourceDispatcherHostImpl::DidReceiveRedirect( | 622 void ResourceDispatcherHostImpl::DidReceiveRedirect( |
602 ResourceLoader* loader, | 623 ResourceLoader* loader, |
603 const GURL& new_url, | 624 const GURL& new_url, |
604 ResourceResponse* response) { | 625 ResourceResponse* response) { |
605 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); | 626 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); |
606 if (delegate_) { | 627 if (delegate_) { |
607 delegate_->OnRequestRedirected( | 628 delegate_->OnRequestRedirected( |
608 new_url, loader->request(), info->GetContext(), response); | 629 new_url, loader->request(), info->GetContext(), response); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
777 void ResourceDispatcherHostImpl::OnInit() { | 798 void ResourceDispatcherHostImpl::OnInit() { |
778 scheduler_.reset(new ResourceScheduler); | 799 scheduler_.reset(new ResourceScheduler); |
779 } | 800 } |
780 | 801 |
781 void ResourceDispatcherHostImpl::OnShutdown() { | 802 void ResourceDispatcherHostImpl::OnShutdown() { |
782 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); | 803 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); |
783 | 804 |
784 is_shutdown_ = true; | 805 is_shutdown_ = true; |
785 pending_loaders_.clear(); | 806 pending_loaders_.clear(); |
786 | 807 |
787 // Make sure we shutdown the timer now, otherwise by the time our destructor | 808 // 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 | 809 // runs if the timer is still running the Task is deleted twice (once by |
789 // the MessageLoop and the second time by RepeatingTimer). | 810 // the MessageLoop and the second time by RepeatingTimer). |
790 update_load_states_timer_.reset(); | 811 update_load_states_timer_.reset(); |
812 record_outstanding_requests_stats_timer_.reset(); | |
791 | 813 |
792 // Clear blocked requests if any left. | 814 // Clear blocked requests if any left. |
793 // Note that we have to do this in 2 passes as we cannot call | 815 // Note that we have to do this in 2 passes as we cannot call |
794 // CancelBlockedRequestsForRoute while iterating over | 816 // CancelBlockedRequestsForRoute while iterating over |
795 // blocked_loaders_map_, as it modifies it. | 817 // blocked_loaders_map_, as it modifies it. |
796 std::set<GlobalFrameRoutingId> ids; | 818 std::set<GlobalFrameRoutingId> ids; |
797 for (const auto& blocked_loaders : blocked_loaders_map_) { | 819 for (const auto& blocked_loaders : blocked_loaders_map_) { |
798 std::pair<std::set<GlobalFrameRoutingId>::iterator, bool> result = | 820 std::pair<std::set<GlobalFrameRoutingId>::iterator, bool> result = |
799 ids.insert(blocked_loaders.first); | 821 ids.insert(blocked_loaders.first); |
800 // We should not have duplicates. | 822 // We should not have duplicates. |
(...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1912 | 1934 |
1913 void ResourceDispatcherHostImpl::UpdateOutstandingRequestsStats( | 1935 void ResourceDispatcherHostImpl::UpdateOutstandingRequestsStats( |
1914 const ResourceRequestInfoImpl& info, | 1936 const ResourceRequestInfoImpl& info, |
1915 const OustandingRequestsStats& stats) { | 1937 const OustandingRequestsStats& stats) { |
1916 if (stats.memory_cost == 0 && stats.num_requests == 0) | 1938 if (stats.memory_cost == 0 && stats.num_requests == 0) |
1917 outstanding_requests_stats_map_.erase(info.GetChildID()); | 1939 outstanding_requests_stats_map_.erase(info.GetChildID()); |
1918 else | 1940 else |
1919 outstanding_requests_stats_map_[info.GetChildID()] = stats; | 1941 outstanding_requests_stats_map_[info.GetChildID()] = stats; |
1920 } | 1942 } |
1921 | 1943 |
1944 void ResourceDispatcherHostImpl::IncrementOutstandingRequestsPerTab( | |
1945 int count, | |
1946 const ResourceRequestInfoImpl& info) { | |
1947 auto key = std::make_pair(info.GetChildID(), info.GetRouteID()); | |
1948 OutstandingRequestsPerTabMap::iterator entry = | |
1949 outstanding_requests_per_tab_map_.insert(std::make_pair(key, 0)).first; | |
1950 entry->second += count; | |
1951 DCHECK_GE(entry->second, 0); | |
1952 if (entry->second == 0) | |
1953 outstanding_requests_per_tab_map_.erase(entry); | |
1954 } | |
1955 | |
1922 ResourceDispatcherHostImpl::OustandingRequestsStats | 1956 ResourceDispatcherHostImpl::OustandingRequestsStats |
1923 ResourceDispatcherHostImpl::IncrementOutstandingRequestsMemory( | 1957 ResourceDispatcherHostImpl::IncrementOutstandingRequestsMemory( |
1924 int count, | 1958 int count, |
1925 const ResourceRequestInfoImpl& info) { | 1959 const ResourceRequestInfoImpl& info) { |
1926 DCHECK_EQ(1, abs(count)); | 1960 DCHECK_EQ(1, abs(count)); |
1927 | 1961 |
1928 // Retrieve the previous value (defaulting to 0 if not found). | 1962 // Retrieve the previous value (defaulting to 0 if not found). |
1929 OustandingRequestsStats stats = GetOutstandingRequestsStats(info); | 1963 OustandingRequestsStats stats = GetOutstandingRequestsStats(info); |
1930 | 1964 |
1931 // Insert/update the total; delete entries when their count reaches 0. | 1965 // 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 | 1981 // in-flight requests for this process, in case we need to transfer it to |
1948 // another process. This should be a toggle. | 1982 // another process. This should be a toggle. |
1949 DCHECK_NE(info->counted_as_in_flight_request(), count > 0); | 1983 DCHECK_NE(info->counted_as_in_flight_request(), count > 0); |
1950 info->set_counted_as_in_flight_request(count > 0); | 1984 info->set_counted_as_in_flight_request(count > 0); |
1951 | 1985 |
1952 OustandingRequestsStats stats = GetOutstandingRequestsStats(*info); | 1986 OustandingRequestsStats stats = GetOutstandingRequestsStats(*info); |
1953 stats.num_requests += count; | 1987 stats.num_requests += count; |
1954 DCHECK_GE(stats.num_requests, 0); | 1988 DCHECK_GE(stats.num_requests, 0); |
1955 UpdateOutstandingRequestsStats(*info, stats); | 1989 UpdateOutstandingRequestsStats(*info, stats); |
1956 | 1990 |
1991 IncrementOutstandingRequestsPerTab(count, *info); | |
1992 | |
1957 if (num_in_flight_requests_ > largest_outstanding_request_count_seen_) { | 1993 if (num_in_flight_requests_ > largest_outstanding_request_count_seen_) { |
1958 largest_outstanding_request_count_seen_ = num_in_flight_requests_; | 1994 largest_outstanding_request_count_seen_ = num_in_flight_requests_; |
1959 UMA_HISTOGRAM_COUNTS_1M( | 1995 UMA_HISTOGRAM_COUNTS_1M( |
1960 "Net.ResourceDispatcherHost.OutstandingRequests.Total", | 1996 "Net.ResourceDispatcherHost.OutstandingRequests.Total", |
1961 largest_outstanding_request_count_seen_); | 1997 largest_outstanding_request_count_seen_); |
1962 } | 1998 } |
1963 | 1999 |
1964 if (stats.num_requests > | 2000 if (stats.num_requests > |
1965 largest_outstanding_request_per_process_count_seen_) { | 2001 largest_outstanding_request_per_process_count_seen_) { |
1966 largest_outstanding_request_per_process_count_seen_ = stats.num_requests; | 2002 largest_outstanding_request_per_process_count_seen_ = stats.num_requests; |
1967 UMA_HISTOGRAM_COUNTS_1M( | 2003 UMA_HISTOGRAM_COUNTS_1M( |
1968 "Net.ResourceDispatcherHost.OutstandingRequests.PerProcess", | 2004 "Net.ResourceDispatcherHost.OutstandingRequests.PerProcess", |
1969 largest_outstanding_request_per_process_count_seen_); | 2005 largest_outstanding_request_per_process_count_seen_); |
1970 } | 2006 } |
1971 | 2007 |
2008 if (num_in_flight_requests_ > peak_outstanding_request_count_) | |
2009 peak_outstanding_request_count_ = num_in_flight_requests_; | |
2010 | |
2011 if (HasRequestsFromMultipleActiveTabs() && | |
2012 num_in_flight_requests_ > peak_outstanding_request_count_multitab_) { | |
2013 peak_outstanding_request_count_multitab_ = num_in_flight_requests_; | |
2014 } | |
2015 | |
1972 return stats; | 2016 return stats; |
1973 } | 2017 } |
1974 | 2018 |
1975 bool ResourceDispatcherHostImpl::HasSufficientResourcesForRequest( | 2019 bool ResourceDispatcherHostImpl::HasSufficientResourcesForRequest( |
1976 net::URLRequest* request) { | 2020 net::URLRequest* request) { |
1977 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); | 2021 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); |
1978 OustandingRequestsStats stats = IncrementOutstandingRequestsCount(1, info); | 2022 OustandingRequestsStats stats = IncrementOutstandingRequestsCount(1, info); |
1979 | 2023 |
1980 if (stats.num_requests > max_num_in_flight_requests_per_process_) | 2024 if (stats.num_requests > max_num_in_flight_requests_per_process_) |
1981 return false; | 2025 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 | 2534 // 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 | 2535 // 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 | 2536 // 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 | 2537 // requests), we must go to the UI thread and compare the requests using their |
2494 // WebContents. | 2538 // WebContents. |
2495 main_thread_task_runner_->PostTask( | 2539 main_thread_task_runner_->PostTask( |
2496 FROM_HERE, | 2540 FROM_HERE, |
2497 base::Bind(UpdateLoadStateOnUI, loader_delegate_, base::Passed(&infos))); | 2541 base::Bind(UpdateLoadStateOnUI, loader_delegate_, base::Passed(&infos))); |
2498 } | 2542 } |
2499 | 2543 |
2544 void ResourceDispatcherHostImpl::RecordOutstandingRequestsStats() { | |
2545 if (peak_outstanding_request_count_ != 0) { | |
2546 UMA_HISTOGRAM_COUNTS_1M( | |
2547 "Net.ResourceDispatcherHost.PeakOutstandingRequests", | |
2548 peak_outstanding_request_count_); | |
2549 peak_outstanding_request_count_ = num_in_flight_requests_; | |
2550 } | |
2551 | |
2552 if (peak_outstanding_request_count_multitab_ != 0) { | |
2553 UMA_HISTOGRAM_COUNTS_1M( | |
2554 "Net.ResourceDispatcherHost.PeakOutstandingRequests.MultiTabLoading", | |
2555 peak_outstanding_request_count_multitab_); | |
2556 peak_outstanding_request_count_multitab_ = | |
2557 HasRequestsFromMultipleActiveTabs() ? num_in_flight_requests_ : 0; | |
2558 } | |
2559 } | |
2560 | |
2500 void ResourceDispatcherHostImpl::BlockRequestsForRoute( | 2561 void ResourceDispatcherHostImpl::BlockRequestsForRoute( |
2501 const GlobalFrameRoutingId& global_routing_id) { | 2562 const GlobalFrameRoutingId& global_routing_id) { |
2502 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); | 2563 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); |
2503 DCHECK(blocked_loaders_map_.find(global_routing_id) == | 2564 DCHECK(blocked_loaders_map_.find(global_routing_id) == |
2504 blocked_loaders_map_.end()) | 2565 blocked_loaders_map_.end()) |
2505 << "BlockRequestsForRoute called multiple time for the same RFH"; | 2566 << "BlockRequestsForRoute called multiple time for the same RFH"; |
2506 blocked_loaders_map_[global_routing_id] = | 2567 blocked_loaders_map_[global_routing_id] = |
2507 base::MakeUnique<BlockedLoadersList>(); | 2568 base::MakeUnique<BlockedLoadersList>(); |
2508 } | 2569 } |
2509 | 2570 |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2699 is_content_initiated, true, is_new_request, | 2760 is_content_initiated, true, is_new_request, |
2700 &throttles); | 2761 &throttles); |
2701 if (!throttles.empty()) { | 2762 if (!throttles.empty()) { |
2702 handler.reset(new ThrottlingResourceHandler(std::move(handler), request, | 2763 handler.reset(new ThrottlingResourceHandler(std::move(handler), request, |
2703 std::move(throttles))); | 2764 std::move(throttles))); |
2704 } | 2765 } |
2705 } | 2766 } |
2706 return handler; | 2767 return handler; |
2707 } | 2768 } |
2708 | 2769 |
2770 bool ResourceDispatcherHostImpl::HasRequestsFromMultipleActiveTabs() { | |
2771 if (outstanding_requests_per_tab_map_.size() < 2) | |
2772 return false; | |
2773 | |
2774 int active_tabs = 0; | |
2775 for (auto iter = outstanding_requests_per_tab_map_.begin(); | |
2776 iter != outstanding_requests_per_tab_map_.end(); ++iter) { | |
2777 if (iter->second > 2) { | |
2778 active_tabs++; | |
2779 if (active_tabs >= 2) | |
2780 return true; | |
2781 } | |
2782 } | |
2783 return false; | |
2784 } | |
2785 | |
2709 } // namespace content | 2786 } // namespace content |
OLD | NEW |