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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 | 108 |
| 109 // ---------------------------------------------------------------------------- | 109 // ---------------------------------------------------------------------------- |
| 110 | 110 |
| 111 namespace content { | 111 namespace content { |
| 112 | 112 |
| 113 namespace { | 113 namespace { |
| 114 | 114 |
| 115 static ResourceDispatcherHostImpl* g_resource_dispatcher_host; | 115 static ResourceDispatcherHostImpl* g_resource_dispatcher_host; |
| 116 | 116 |
| 117 // The interval for calls to ResourceDispatcherHostImpl::UpdateLoadStates | 117 // The interval for calls to ResourceDispatcherHostImpl::UpdateLoadStates |
| 118 const int kUpdateLoadStatesIntervalMsec = 100; | 118 const int kUpdateLoadStatesIntervalMsec = 250; |
| 119 | 119 |
| 120 // Maximum byte "cost" of all the outstanding requests for a renderer. | 120 // Maximum byte "cost" of all the outstanding requests for a renderer. |
| 121 // See delcaration of |max_outstanding_requests_cost_per_process_| for details. | 121 // See delcaration of |max_outstanding_requests_cost_per_process_| for details. |
| 122 // This bound is 25MB, which allows for around 6000 outstanding requests. | 122 // This bound is 25MB, which allows for around 6000 outstanding requests. |
| 123 const int kMaxOutstandingRequestsCostPerProcess = 26214400; | 123 const int kMaxOutstandingRequestsCostPerProcess = 26214400; |
| 124 | 124 |
| 125 // The number of milliseconds after noting a user gesture that we will | 125 // The number of milliseconds after noting a user gesture that we will |
| 126 // tag newly-created URLRequest objects with the | 126 // tag newly-created URLRequest objects with the |
| 127 // net::LOAD_MAYBE_USER_GESTURE load flag. This is a fairly arbitrary | 127 // net::LOAD_MAYBE_USER_GESTURE load flag. This is a fairly arbitrary |
| 128 // guess at how long to expect direct impact from a user gesture, but | 128 // 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... | |
| 446 ANNOTATE_BENIGN_RACE( | 446 ANNOTATE_BENIGN_RACE( |
| 447 &last_user_gesture_time_, | 447 &last_user_gesture_time_, |
| 448 "We don't care about the precise value, see http://crbug.com/92889"); | 448 "We don't care about the precise value, see http://crbug.com/92889"); |
| 449 | 449 |
| 450 BrowserThread::PostTask(BrowserThread::IO, | 450 BrowserThread::PostTask(BrowserThread::IO, |
| 451 FROM_HERE, | 451 FROM_HERE, |
| 452 base::Bind(&ResourceDispatcherHostImpl::OnInit, | 452 base::Bind(&ResourceDispatcherHostImpl::OnInit, |
| 453 base::Unretained(this))); | 453 base::Unretained(this))); |
| 454 | 454 |
| 455 update_load_states_timer_.reset( | 455 update_load_states_timer_.reset( |
| 456 new base::RepeatingTimer<ResourceDispatcherHostImpl>()); | 456 new base::OneShotTimer<ResourceDispatcherHostImpl>()); |
| 457 } | 457 } |
| 458 | 458 |
| 459 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { | 459 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { |
| 460 DCHECK(outstanding_requests_stats_map_.empty()); | 460 DCHECK(outstanding_requests_stats_map_.empty()); |
| 461 DCHECK(g_resource_dispatcher_host); | 461 DCHECK(g_resource_dispatcher_host); |
| 462 g_resource_dispatcher_host = NULL; | 462 g_resource_dispatcher_host = NULL; |
| 463 } | 463 } |
| 464 | 464 |
| 465 // static | 465 // static |
| 466 ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() { | 466 ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() { |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 781 info->GetContext()->GetRequestContext()->job_factory(); | 781 info->GetContext()->GetRequestContext()->job_factory(); |
| 782 if (job_factory->IsHandledURL(url)) | 782 if (job_factory->IsHandledURL(url)) |
| 783 return false; | 783 return false; |
| 784 | 784 |
| 785 return delegate_->HandleExternalProtocol( | 785 return delegate_->HandleExternalProtocol( |
| 786 url, info->GetChildID(), info->GetRouteID(), info->IsMainFrame(), | 786 url, info->GetChildID(), info->GetRouteID(), info->IsMainFrame(), |
| 787 info->GetPageTransition(), info->HasUserGesture()); | 787 info->GetPageTransition(), info->HasUserGesture()); |
| 788 } | 788 } |
| 789 | 789 |
| 790 void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) { | 790 void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) { |
| 791 // Make sure we have the load state monitor running | 791 if (scheduler_->HasLoadingClients()) |
| 792 if (!update_load_states_timer_->IsRunning()) { | 792 ScheduleUpdateLoadInfo(); |
| 793 update_load_states_timer_->Start( | |
| 794 FROM_HERE, TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec), | |
| 795 this, &ResourceDispatcherHostImpl::UpdateLoadInfo); | |
| 796 } | |
| 797 } | 793 } |
| 798 | 794 |
| 799 void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader, | 795 void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader, |
| 800 const GURL& new_url) { | 796 const GURL& new_url) { |
| 801 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); | 797 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); |
| 802 | 798 |
| 803 int render_process_id, render_frame_host; | 799 int render_process_id, render_frame_host; |
| 804 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host)) | 800 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host)) |
| 805 return; | 801 return; |
| 806 | 802 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 933 } | 929 } |
| 934 | 930 |
| 935 void ResourceDispatcherHostImpl::OnShutdown() { | 931 void ResourceDispatcherHostImpl::OnShutdown() { |
| 936 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 932 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 937 | 933 |
| 938 is_shutdown_ = true; | 934 is_shutdown_ = true; |
| 939 pending_loaders_.clear(); | 935 pending_loaders_.clear(); |
| 940 | 936 |
| 941 // Make sure we shutdown the timer now, otherwise by the time our destructor | 937 // Make sure we shutdown the timer now, otherwise by the time our destructor |
| 942 // runs if the timer is still running the Task is deleted twice (once by | 938 // runs if the timer is still running the Task is deleted twice (once by |
| 943 // the MessageLoop and the second time by RepeatingTimer). | 939 // the MessageLoop and the second time by OneShotTimer). |
| 944 update_load_states_timer_.reset(); | 940 update_load_states_timer_.reset(); |
| 945 | 941 |
| 946 // Clear blocked requests if any left. | 942 // Clear blocked requests if any left. |
| 947 // Note that we have to do this in 2 passes as we cannot call | 943 // Note that we have to do this in 2 passes as we cannot call |
| 948 // CancelBlockedRequestsForRoute while iterating over | 944 // CancelBlockedRequestsForRoute while iterating over |
| 949 // blocked_loaders_map_, as it modifies it. | 945 // blocked_loaders_map_, as it modifies it. |
| 950 std::set<GlobalRoutingID> ids; | 946 std::set<GlobalRoutingID> ids; |
| 951 for (BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.begin(); | 947 for (BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.begin(); |
| 952 iter != blocked_loaders_map_.end(); ++iter) { | 948 iter != blocked_loaders_map_.end(); ++iter) { |
| 953 std::pair<std::set<GlobalRoutingID>::iterator, bool> result = | 949 std::pair<std::set<GlobalRoutingID>::iterator, bool> result = |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1774 | 1770 |
| 1775 void ResourceDispatcherHostImpl::RemovePendingLoader( | 1771 void ResourceDispatcherHostImpl::RemovePendingLoader( |
| 1776 const LoaderMap::iterator& iter) { | 1772 const LoaderMap::iterator& iter) { |
| 1777 ResourceRequestInfoImpl* info = iter->second->GetRequestInfo(); | 1773 ResourceRequestInfoImpl* info = iter->second->GetRequestInfo(); |
| 1778 | 1774 |
| 1779 // Remove the memory credit that we added when pushing the request onto | 1775 // Remove the memory credit that we added when pushing the request onto |
| 1780 // the pending list. | 1776 // the pending list. |
| 1781 IncrementOutstandingRequestsMemory(-1, *info); | 1777 IncrementOutstandingRequestsMemory(-1, *info); |
| 1782 | 1778 |
| 1783 pending_loaders_.erase(iter); | 1779 pending_loaders_.erase(iter); |
| 1784 | |
| 1785 // If we have no more pending requests, then stop the load state monitor | |
| 1786 if (pending_loaders_.empty() && update_load_states_timer_) | |
| 1787 update_load_states_timer_->Stop(); | |
| 1788 } | 1780 } |
| 1789 | 1781 |
| 1790 void ResourceDispatcherHostImpl::CancelRequest(int child_id, | 1782 void ResourceDispatcherHostImpl::CancelRequest(int child_id, |
| 1791 int request_id) { | 1783 int request_id) { |
| 1792 ResourceLoader* loader = GetLoader(child_id, request_id); | 1784 ResourceLoader* loader = GetLoader(child_id, request_id); |
| 1793 if (!loader) { | 1785 if (!loader) { |
| 1794 // We probably want to remove this warning eventually, but I wanted to be | 1786 // We probably want to remove this warning eventually, but I wanted to be |
| 1795 // able to notice when this happens during initial development since it | 1787 // able to notice when this happens during initial development since it |
| 1796 // should be rare and may indicate a bug. | 1788 // should be rare and may indicate a bug. |
| 1797 DVLOG(1) << "Canceling a request that wasn't found"; | 1789 DVLOG(1) << "Canceling a request that wasn't found"; |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2160 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2152 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 2161 "466285 ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread")); | 2153 "466285 ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread")); |
| 2162 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 2154 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 2163 for (const auto& load_info : *info_map) { | 2155 for (const auto& load_info : *info_map) { |
| 2164 RenderViewHostImpl* view = RenderViewHostImpl::FromID( | 2156 RenderViewHostImpl* view = RenderViewHostImpl::FromID( |
| 2165 load_info.first.child_id, load_info.first.route_id); | 2157 load_info.first.child_id, load_info.first.route_id); |
| 2166 // The view could be gone at this point. | 2158 // The view could be gone at this point. |
| 2167 if (view) { | 2159 if (view) { |
| 2168 view->LoadStateChanged(load_info.second.url, load_info.second.load_state, | 2160 view->LoadStateChanged(load_info.second.url, load_info.second.load_state, |
| 2169 load_info.second.upload_position, | 2161 load_info.second.upload_position, |
| 2170 load_info.second.upload_size); | 2162 load_info.second.upload_size); |
|
mmenke
2015/05/21 15:53:25
You should consider updating the GetLoadState() do
Andre
2015/05/21 22:05:39
Done.
| |
| 2171 } | 2163 } |
| 2172 } | 2164 } |
| 2173 } | 2165 } |
| 2174 | 2166 |
| 2175 scoped_ptr<ResourceDispatcherHostImpl::LoadInfoMap> | 2167 scoped_ptr<ResourceDispatcherHostImpl::LoadInfoMap> |
| 2176 ResourceDispatcherHostImpl::GetLoadInfoForAllRoutes() { | 2168 ResourceDispatcherHostImpl::GetLoadInfoForAllRoutes() { |
| 2177 // Populate this map with load state changes, and then send them on to the UI | 2169 // Populate this map with load state changes, and then send them on to the UI |
| 2178 // thread where they can be passed along to the respective RVHs. | 2170 // thread where they can be passed along to the respective RVHs. |
| 2179 scoped_ptr<LoadInfoMap> info_map(new LoadInfoMap()); | 2171 scoped_ptr<LoadInfoMap> info_map(new LoadInfoMap()); |
| 2180 | 2172 |
| 2181 for (const auto& loader : pending_loaders_) { | 2173 for (const auto& loader : pending_loaders_) { |
|
mmenke
2015/05/21 15:53:25
Should actually remove this call in the other CL.
Andre
2015/05/21 22:05:39
Done.
| |
| 2182 // Also poll for upload progress on this timer and send upload progress ipc | |
| 2183 // messages to the plugin process. | |
| 2184 loader.second->ReportUploadProgress(); | |
| 2185 | |
| 2186 net::URLRequest* request = loader.second->request(); | 2174 net::URLRequest* request = loader.second->request(); |
| 2187 net::UploadProgress upload_progress = request->GetUploadProgress(); | 2175 net::UploadProgress upload_progress = request->GetUploadProgress(); |
| 2188 | 2176 |
| 2189 LoadInfo load_info; | 2177 LoadInfo load_info; |
| 2190 load_info.url = request->url(); | 2178 load_info.url = request->url(); |
| 2191 load_info.load_state = request->GetLoadState(); | 2179 load_info.load_state = request->GetLoadState(); |
| 2192 load_info.upload_size = upload_progress.size(); | 2180 load_info.upload_size = upload_progress.size(); |
| 2193 load_info.upload_position = upload_progress.position(); | 2181 load_info.upload_position = upload_progress.position(); |
| 2194 | 2182 |
| 2195 GlobalRoutingID id(loader.second->GetRequestInfo()->GetGlobalRoutingID()); | 2183 GlobalRoutingID id(loader.second->GetRequestInfo()->GetGlobalRoutingID()); |
| 2196 LoadInfoMap::iterator existing = info_map->find(id); | 2184 LoadInfoMap::iterator existing = info_map->find(id); |
| 2197 | 2185 |
| 2198 if (existing == info_map->end() || | 2186 if (existing == info_map->end() || |
| 2199 LoadInfoIsMoreInteresting(load_info, existing->second)) { | 2187 LoadInfoIsMoreInteresting(load_info, existing->second)) { |
| 2200 (*info_map)[id] = load_info; | 2188 (*info_map)[id] = load_info; |
| 2201 } | 2189 } |
| 2202 } | 2190 } |
| 2203 return info_map.Pass(); | 2191 return info_map.Pass(); |
| 2204 } | 2192 } |
| 2205 | 2193 |
| 2206 void ResourceDispatcherHostImpl::UpdateLoadInfo() { | 2194 void ResourceDispatcherHostImpl::UpdateLoadInfo() { |
| 2207 scoped_ptr<LoadInfoMap> info_map(GetLoadInfoForAllRoutes()); | 2195 scoped_ptr<LoadInfoMap> info_map(GetLoadInfoForAllRoutes()); |
| 2208 | 2196 |
| 2209 if (info_map->empty()) | 2197 if (info_map->empty()) |
| 2210 return; | 2198 return; |
|
mmenke
2015/05/21 15:53:25
I think a repeating timer with an explicit Stop()
Andre
2015/05/21 22:05:39
You're right. Now that the upload progress code is
| |
| 2211 | 2199 |
| 2212 BrowserThread::PostTask( | 2200 BrowserThread::PostTask( |
| 2213 BrowserThread::UI, FROM_HERE, | 2201 BrowserThread::UI, FROM_HERE, |
| 2214 base::Bind(&ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread, | 2202 base::Bind(&ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread, |
| 2215 base::Passed(&info_map))); | 2203 base::Passed(&info_map))); |
| 2204 | |
| 2205 if (scheduler_->HasLoadingClients()) | |
| 2206 ScheduleUpdateLoadInfo(); | |
|
mmenke
2015/05/21 15:53:25
Should use 2 space indent here, not 3
Andre
2015/05/21 22:05:39
Done.
| |
| 2216 } | 2207 } |
| 2217 | 2208 |
| 2218 void ResourceDispatcherHostImpl::BlockRequestsForRoute(int child_id, | 2209 void ResourceDispatcherHostImpl::BlockRequestsForRoute(int child_id, |
| 2219 int route_id) { | 2210 int route_id) { |
| 2220 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 2211 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 2221 GlobalRoutingID key(child_id, route_id); | 2212 GlobalRoutingID key(child_id, route_id); |
| 2222 DCHECK(blocked_loaders_map_.find(key) == blocked_loaders_map_.end()) << | 2213 DCHECK(blocked_loaders_map_.find(key) == blocked_loaders_map_.end()) << |
| 2223 "BlockRequestsForRoute called multiple time for the same RVH"; | 2214 "BlockRequestsForRoute called multiple time for the same RVH"; |
| 2224 blocked_loaders_map_[key] = new BlockedLoadersList(); | 2215 blocked_loaders_map_[key] = new BlockedLoadersList(); |
| 2225 } | 2216 } |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2368 } | 2359 } |
| 2369 | 2360 |
| 2370 // Add a flag to selectively bypass the data reduction proxy if the resource | 2361 // Add a flag to selectively bypass the data reduction proxy if the resource |
| 2371 // type is not an image. | 2362 // type is not an image. |
| 2372 if (request_data.resource_type != RESOURCE_TYPE_IMAGE) | 2363 if (request_data.resource_type != RESOURCE_TYPE_IMAGE) |
| 2373 load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY; | 2364 load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY; |
| 2374 | 2365 |
| 2375 return load_flags; | 2366 return load_flags; |
| 2376 } | 2367 } |
| 2377 | 2368 |
| 2369 void ResourceDispatcherHostImpl::ScheduleUpdateLoadInfo() { | |
| 2370 if (!update_load_states_timer_->IsRunning()) { | |
|
mmenke
2015/05/21 15:53:25
Suggest early return instead - it's generally pref
Andre
2015/05/21 22:05:39
Done.
| |
| 2371 update_load_states_timer_->Start( | |
| 2372 FROM_HERE, TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec), | |
| 2373 this, &ResourceDispatcherHostImpl::UpdateLoadInfo); | |
| 2374 } | |
| 2375 } | |
| 2376 | |
| 2378 } // namespace content | 2377 } // namespace content |
| OLD | NEW |