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 <algorithm> | 9 #include <algorithm> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 | 107 |
| 108 // ---------------------------------------------------------------------------- | 108 // ---------------------------------------------------------------------------- |
| 109 | 109 |
| 110 namespace content { | 110 namespace content { |
| 111 | 111 |
| 112 namespace { | 112 namespace { |
| 113 | 113 |
| 114 static ResourceDispatcherHostImpl* g_resource_dispatcher_host; | 114 static ResourceDispatcherHostImpl* g_resource_dispatcher_host; |
| 115 | 115 |
| 116 // The interval for calls to ResourceDispatcherHostImpl::UpdateLoadStates | 116 // The interval for calls to ResourceDispatcherHostImpl::UpdateLoadStates |
| 117 const int kUpdateLoadStatesIntervalMsec = 100; | 117 const int kUpdateLoadStatesIntervalMsec = 100; |
|
Andre
2015/05/07 19:31:49
Do you think this should be increased?
The status
mmenke
2015/05/07 19:49:29
I think 200 ms would be fine, and we could experim
Andre
2015/05/20 23:05:32
How about 250ms ;-D
| |
| 118 | 118 |
| 119 // Maximum byte "cost" of all the outstanding requests for a renderer. | 119 // Maximum byte "cost" of all the outstanding requests for a renderer. |
| 120 // See delcaration of |max_outstanding_requests_cost_per_process_| for details. | 120 // See delcaration of |max_outstanding_requests_cost_per_process_| for details. |
| 121 // This bound is 25MB, which allows for around 6000 outstanding requests. | 121 // This bound is 25MB, which allows for around 6000 outstanding requests. |
| 122 const int kMaxOutstandingRequestsCostPerProcess = 26214400; | 122 const int kMaxOutstandingRequestsCostPerProcess = 26214400; |
| 123 | 123 |
| 124 // The number of milliseconds after noting a user gesture that we will | 124 // The number of milliseconds after noting a user gesture that we will |
| 125 // tag newly-created URLRequest objects with the | 125 // tag newly-created URLRequest objects with the |
| 126 // net::LOAD_MAYBE_USER_GESTURE load flag. This is a fairly arbitrary | 126 // net::LOAD_MAYBE_USER_GESTURE load flag. This is a fairly arbitrary |
| 127 // guess at how long to expect direct impact from a user gesture, but | 127 // guess at how long to expect direct impact from a user gesture, but |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 ANNOTATE_BENIGN_RACE( | 445 ANNOTATE_BENIGN_RACE( |
| 446 &last_user_gesture_time_, | 446 &last_user_gesture_time_, |
| 447 "We don't care about the precise value, see http://crbug.com/92889"); | 447 "We don't care about the precise value, see http://crbug.com/92889"); |
| 448 | 448 |
| 449 BrowserThread::PostTask(BrowserThread::IO, | 449 BrowserThread::PostTask(BrowserThread::IO, |
| 450 FROM_HERE, | 450 FROM_HERE, |
| 451 base::Bind(&ResourceDispatcherHostImpl::OnInit, | 451 base::Bind(&ResourceDispatcherHostImpl::OnInit, |
| 452 base::Unretained(this))); | 452 base::Unretained(this))); |
| 453 | 453 |
| 454 update_load_states_timer_.reset( | 454 update_load_states_timer_.reset( |
| 455 new base::RepeatingTimer<ResourceDispatcherHostImpl>()); | 455 new base::OneShotTimer<ResourceDispatcherHostImpl>()); |
| 456 } | 456 } |
| 457 | 457 |
| 458 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { | 458 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { |
| 459 DCHECK(outstanding_requests_stats_map_.empty()); | 459 DCHECK(outstanding_requests_stats_map_.empty()); |
| 460 DCHECK(g_resource_dispatcher_host); | 460 DCHECK(g_resource_dispatcher_host); |
| 461 g_resource_dispatcher_host = NULL; | 461 g_resource_dispatcher_host = NULL; |
| 462 } | 462 } |
| 463 | 463 |
| 464 // static | 464 // static |
| 465 ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() { | 465 ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() { |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 790 const net::URLRequestJobFactory* job_factory = | 790 const net::URLRequestJobFactory* job_factory = |
| 791 info->GetContext()->GetRequestContext()->job_factory(); | 791 info->GetContext()->GetRequestContext()->job_factory(); |
| 792 if (job_factory->IsHandledURL(url)) | 792 if (job_factory->IsHandledURL(url)) |
| 793 return false; | 793 return false; |
| 794 | 794 |
| 795 return delegate_->HandleExternalProtocol( | 795 return delegate_->HandleExternalProtocol( |
| 796 url, info->GetChildID(), info->GetRouteID()); | 796 url, info->GetChildID(), info->GetRouteID()); |
| 797 } | 797 } |
| 798 | 798 |
| 799 void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) { | 799 void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) { |
| 800 // Make sure we have the load state monitor running | 800 if (scheduler_->HasLoadingClients() || loader->request()->has_upload()) |
| 801 if (!update_load_states_timer_->IsRunning()) { | 801 ScheduleUpdateLoadInfo(); |
| 802 update_load_states_timer_->Start( | |
| 803 FROM_HERE, TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec), | |
| 804 this, &ResourceDispatcherHostImpl::UpdateLoadInfo); | |
| 805 } | |
| 806 } | 802 } |
| 807 | 803 |
| 808 void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader, | 804 void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader, |
| 809 const GURL& new_url) { | 805 const GURL& new_url) { |
| 810 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); | 806 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); |
| 811 | 807 |
| 812 int render_process_id, render_frame_host; | 808 int render_process_id, render_frame_host; |
| 813 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host)) | 809 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host)) |
| 814 return; | 810 return; |
| 815 | 811 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 903 } | 899 } |
| 904 | 900 |
| 905 void ResourceDispatcherHostImpl::OnShutdown() { | 901 void ResourceDispatcherHostImpl::OnShutdown() { |
| 906 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 902 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 907 | 903 |
| 908 is_shutdown_ = true; | 904 is_shutdown_ = true; |
| 909 pending_loaders_.clear(); | 905 pending_loaders_.clear(); |
| 910 | 906 |
| 911 // Make sure we shutdown the timer now, otherwise by the time our destructor | 907 // Make sure we shutdown the timer now, otherwise by the time our destructor |
| 912 // runs if the timer is still running the Task is deleted twice (once by | 908 // runs if the timer is still running the Task is deleted twice (once by |
| 913 // the MessageLoop and the second time by RepeatingTimer). | 909 // the MessageLoop and the second time by OneShotTimer). |
| 914 update_load_states_timer_.reset(); | 910 update_load_states_timer_.reset(); |
| 915 | 911 |
| 916 // Clear blocked requests if any left. | 912 // Clear blocked requests if any left. |
| 917 // Note that we have to do this in 2 passes as we cannot call | 913 // Note that we have to do this in 2 passes as we cannot call |
| 918 // CancelBlockedRequestsForRoute while iterating over | 914 // CancelBlockedRequestsForRoute while iterating over |
| 919 // blocked_loaders_map_, as it modifies it. | 915 // blocked_loaders_map_, as it modifies it. |
| 920 std::set<GlobalRoutingID> ids; | 916 std::set<GlobalRoutingID> ids; |
| 921 for (BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.begin(); | 917 for (BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.begin(); |
| 922 iter != blocked_loaders_map_.end(); ++iter) { | 918 iter != blocked_loaders_map_.end(); ++iter) { |
| 923 std::pair<std::set<GlobalRoutingID>::iterator, bool> result = | 919 std::pair<std::set<GlobalRoutingID>::iterator, bool> result = |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1744 | 1740 |
| 1745 void ResourceDispatcherHostImpl::RemovePendingLoader( | 1741 void ResourceDispatcherHostImpl::RemovePendingLoader( |
| 1746 const LoaderMap::iterator& iter) { | 1742 const LoaderMap::iterator& iter) { |
| 1747 ResourceRequestInfoImpl* info = iter->second->GetRequestInfo(); | 1743 ResourceRequestInfoImpl* info = iter->second->GetRequestInfo(); |
| 1748 | 1744 |
| 1749 // Remove the memory credit that we added when pushing the request onto | 1745 // Remove the memory credit that we added when pushing the request onto |
| 1750 // the pending list. | 1746 // the pending list. |
| 1751 IncrementOutstandingRequestsMemory(-1, *info); | 1747 IncrementOutstandingRequestsMemory(-1, *info); |
| 1752 | 1748 |
| 1753 pending_loaders_.erase(iter); | 1749 pending_loaders_.erase(iter); |
| 1754 | |
| 1755 // If we have no more pending requests, then stop the load state monitor | |
| 1756 if (pending_loaders_.empty() && update_load_states_timer_) | |
| 1757 update_load_states_timer_->Stop(); | |
| 1758 } | 1750 } |
| 1759 | 1751 |
| 1760 void ResourceDispatcherHostImpl::CancelRequest(int child_id, | 1752 void ResourceDispatcherHostImpl::CancelRequest(int child_id, |
| 1761 int request_id) { | 1753 int request_id) { |
| 1762 ResourceLoader* loader = GetLoader(child_id, request_id); | 1754 ResourceLoader* loader = GetLoader(child_id, request_id); |
| 1763 if (!loader) { | 1755 if (!loader) { |
| 1764 // We probably want to remove this warning eventually, but I wanted to be | 1756 // We probably want to remove this warning eventually, but I wanted to be |
| 1765 // able to notice when this happens during initial development since it | 1757 // able to notice when this happens during initial development since it |
| 1766 // should be rare and may indicate a bug. | 1758 // should be rare and may indicate a bug. |
| 1767 DVLOG(1) << "Canceling a request that wasn't found"; | 1759 DVLOG(1) << "Canceling a request that wasn't found"; |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2143 load_info.second.upload_size); | 2135 load_info.second.upload_size); |
| 2144 } | 2136 } |
| 2145 } | 2137 } |
| 2146 } | 2138 } |
| 2147 | 2139 |
| 2148 scoped_ptr<ResourceDispatcherHostImpl::LoadInfoMap> | 2140 scoped_ptr<ResourceDispatcherHostImpl::LoadInfoMap> |
| 2149 ResourceDispatcherHostImpl::GetLoadInfoForAllRoutes() { | 2141 ResourceDispatcherHostImpl::GetLoadInfoForAllRoutes() { |
| 2150 // Populate this map with load state changes, and then send them on to the UI | 2142 // Populate this map with load state changes, and then send them on to the UI |
| 2151 // thread where they can be passed along to the respective RVHs. | 2143 // thread where they can be passed along to the respective RVHs. |
| 2152 scoped_ptr<LoadInfoMap> info_map(new LoadInfoMap()); | 2144 scoped_ptr<LoadInfoMap> info_map(new LoadInfoMap()); |
| 2145 bool uploading = false; | |
| 2153 | 2146 |
| 2154 for (const auto& loader : pending_loaders_) { | 2147 for (const auto& loader : pending_loaders_) { |
| 2148 net::URLRequest* request = loader.second->request(); | |
| 2149 net::UploadProgress upload_progress = request->GetUploadProgress(); | |
| 2150 | |
| 2155 // Also poll for upload progress on this timer and send upload progress ipc | 2151 // Also poll for upload progress on this timer and send upload progress ipc |
| 2156 // messages to the plugin process. | 2152 // messages to the plugin process. |
| 2157 loader.second->ReportUploadProgress(); | 2153 if (request->has_upload()) { |
| 2158 | 2154 loader.second->ReportUploadProgress(); |
| 2159 net::URLRequest* request = loader.second->request(); | 2155 uploading = true; |
| 2160 net::UploadProgress upload_progress = request->GetUploadProgress(); | 2156 } |
| 2161 | 2157 |
| 2162 LoadInfo load_info; | 2158 LoadInfo load_info; |
| 2163 load_info.url = request->url(); | 2159 load_info.url = request->url(); |
| 2164 load_info.load_state = request->GetLoadState(); | 2160 load_info.load_state = request->GetLoadState(); |
| 2165 load_info.upload_size = upload_progress.size(); | 2161 load_info.upload_size = upload_progress.size(); |
| 2166 load_info.upload_position = upload_progress.position(); | 2162 load_info.upload_position = upload_progress.position(); |
| 2167 | 2163 |
| 2168 GlobalRoutingID id(loader.second->GetRequestInfo()->GetGlobalRoutingID()); | 2164 GlobalRoutingID id(loader.second->GetRequestInfo()->GetGlobalRoutingID()); |
| 2169 LoadInfoMap::iterator existing = info_map->find(id); | 2165 LoadInfoMap::iterator existing = info_map->find(id); |
| 2170 | 2166 |
| 2171 if (existing == info_map->end() || | 2167 if (existing == info_map->end() || |
| 2172 LoadInfoIsMoreInteresting(load_info, existing->second)) { | 2168 LoadInfoIsMoreInteresting(load_info, existing->second)) { |
| 2173 (*info_map)[id] = load_info; | 2169 (*info_map)[id] = load_info; |
| 2174 } | 2170 } |
| 2175 } | 2171 } |
| 2172 | |
| 2173 if (uploading) | |
| 2174 ScheduleUpdateLoadInfo(); | |
| 2175 | |
| 2176 return info_map.Pass(); | 2176 return info_map.Pass(); |
| 2177 } | 2177 } |
| 2178 | 2178 |
| 2179 void ResourceDispatcherHostImpl::UpdateLoadInfo() { | 2179 void ResourceDispatcherHostImpl::UpdateLoadInfo() { |
| 2180 scoped_ptr<LoadInfoMap> info_map(GetLoadInfoForAllRoutes()); | 2180 scoped_ptr<LoadInfoMap> info_map(GetLoadInfoForAllRoutes()); |
| 2181 | 2181 |
| 2182 if (info_map->empty()) | 2182 if (info_map->empty()) |
| 2183 return; | 2183 return; |
| 2184 | 2184 |
| 2185 BrowserThread::PostTask( | 2185 BrowserThread::PostTask( |
| 2186 BrowserThread::UI, FROM_HERE, | 2186 BrowserThread::UI, FROM_HERE, |
| 2187 base::Bind(&ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread, | 2187 base::Bind(&ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread, |
| 2188 base::Passed(&info_map))); | 2188 base::Passed(&info_map))); |
| 2189 | |
| 2190 if (scheduler_->HasLoadingClients()) | |
| 2191 ScheduleUpdateLoadInfo(); | |
| 2189 } | 2192 } |
| 2190 | 2193 |
| 2191 void ResourceDispatcherHostImpl::BlockRequestsForRoute(int child_id, | 2194 void ResourceDispatcherHostImpl::BlockRequestsForRoute(int child_id, |
| 2192 int route_id) { | 2195 int route_id) { |
| 2193 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 2196 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 2194 GlobalRoutingID key(child_id, route_id); | 2197 GlobalRoutingID key(child_id, route_id); |
| 2195 DCHECK(blocked_loaders_map_.find(key) == blocked_loaders_map_.end()) << | 2198 DCHECK(blocked_loaders_map_.find(key) == blocked_loaders_map_.end()) << |
| 2196 "BlockRequestsForRoute called multiple time for the same RVH"; | 2199 "BlockRequestsForRoute called multiple time for the same RVH"; |
| 2197 blocked_loaders_map_[key] = new BlockedLoadersList(); | 2200 blocked_loaders_map_[key] = new BlockedLoadersList(); |
| 2198 } | 2201 } |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2343 } | 2346 } |
| 2344 | 2347 |
| 2345 // Add a flag to selectively bypass the data reduction proxy if the resource | 2348 // Add a flag to selectively bypass the data reduction proxy if the resource |
| 2346 // type is not an image. | 2349 // type is not an image. |
| 2347 if (request_data.resource_type != RESOURCE_TYPE_IMAGE) | 2350 if (request_data.resource_type != RESOURCE_TYPE_IMAGE) |
| 2348 load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY; | 2351 load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY; |
| 2349 | 2352 |
| 2350 return load_flags; | 2353 return load_flags; |
| 2351 } | 2354 } |
| 2352 | 2355 |
| 2356 void ResourceDispatcherHostImpl::ScheduleUpdateLoadInfo() { | |
| 2357 if (!update_load_states_timer_->IsRunning()) { | |
| 2358 update_load_states_timer_->Start( | |
| 2359 FROM_HERE, TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec), | |
| 2360 this, &ResourceDispatcherHostImpl::UpdateLoadInfo); | |
| 2361 } | |
| 2362 } | |
| 2363 | |
| 2353 } // namespace content | 2364 } // namespace content |
| OLD | NEW |