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 |