Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: content/browser/renderer_host/render_process_host_impl.cc

Issue 10575014: Move process-per-site logic from BrowsingInstance to RenderProcessHost. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix review comment. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 // Represents the browser side of the browser <--> renderer communication 5 // Represents the browser side of the browser <--> renderer communication
6 // channel. There will be one RenderProcessHost per renderer process. 6 // channel. There will be one RenderProcessHost per renderer process.
7 7
8 #include "content/browser/renderer_host/render_process_host_impl.h" 8 #include "content/browser/renderer_host/render_process_host_impl.h"
9 9
10 #if defined(OS_WIN) 10 #if defined(OS_WIN)
(...skipping 17 matching lines...) Expand all
28 #include "base/lazy_instance.h" 28 #include "base/lazy_instance.h"
29 #include "base/logging.h" 29 #include "base/logging.h"
30 #include "base/metrics/field_trial.h" 30 #include "base/metrics/field_trial.h"
31 #include "base/metrics/histogram.h" 31 #include "base/metrics/histogram.h"
32 #include "base/path_service.h" 32 #include "base/path_service.h"
33 #include "base/platform_file.h" 33 #include "base/platform_file.h"
34 #include "base/process_util.h" 34 #include "base/process_util.h"
35 #include "base/rand_util.h" 35 #include "base/rand_util.h"
36 #include "base/stl_util.h" 36 #include "base/stl_util.h"
37 #include "base/string_util.h" 37 #include "base/string_util.h"
38 #include "base/supports_user_data.h"
38 #include "base/sys_info.h" 39 #include "base/sys_info.h"
39 #include "base/threading/thread.h" 40 #include "base/threading/thread.h"
40 #include "base/threading/thread_restrictions.h" 41 #include "base/threading/thread_restrictions.h"
41 #include "base/tracked_objects.h" 42 #include "base/tracked_objects.h"
42 #include "content/browser/appcache/appcache_dispatcher_host.h" 43 #include "content/browser/appcache/appcache_dispatcher_host.h"
43 #include "content/browser/appcache/chrome_appcache_service.h" 44 #include "content/browser/appcache/chrome_appcache_service.h"
44 #include "content/browser/browser_main.h" 45 #include "content/browser/browser_main.h"
45 #include "content/browser/browser_main_loop.h" 46 #include "content/browser/browser_main_loop.h"
46 #include "content/browser/child_process_security_policy_impl.h" 47 #include "content/browser/child_process_security_policy_impl.h"
47 #include "content/browser/device_orientation/message_filter.h" 48 #include "content/browser/device_orientation/message_filter.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 #include "content/browser/trace_message_filter.h" 85 #include "content/browser/trace_message_filter.h"
85 #include "content/browser/worker_host/worker_message_filter.h" 86 #include "content/browser/worker_host/worker_message_filter.h"
86 #include "content/common/child_process_host_impl.h" 87 #include "content/common/child_process_host_impl.h"
87 #include "content/common/child_process_messages.h" 88 #include "content/common/child_process_messages.h"
88 #include "content/common/gpu/gpu_messages.h" 89 #include "content/common/gpu/gpu_messages.h"
89 #include "content/common/resource_messages.h" 90 #include "content/common/resource_messages.h"
90 #include "content/common/view_messages.h" 91 #include "content/common/view_messages.h"
91 #include "content/public/browser/browser_context.h" 92 #include "content/public/browser/browser_context.h"
92 #include "content/public/browser/content_browser_client.h" 93 #include "content/public/browser/content_browser_client.h"
93 #include "content/public/browser/notification_service.h" 94 #include "content/public/browser/notification_service.h"
95 #include "content/public/browser/render_process_host_factory.h"
94 #include "content/public/browser/resource_context.h" 96 #include "content/public/browser/resource_context.h"
95 #include "content/public/browser/user_metrics.h" 97 #include "content/public/browser/user_metrics.h"
96 #include "content/public/browser/web_ui_controller_factory.h" 98 #include "content/public/browser/web_ui_controller_factory.h"
97 #include "content/public/common/content_constants.h" 99 #include "content/public/common/content_constants.h"
98 #include "content/public/common/content_switches.h" 100 #include "content/public/common/content_switches.h"
99 #include "content/public/common/process_type.h" 101 #include "content/public/common/process_type.h"
100 #include "content/public/common/result_codes.h" 102 #include "content/public/common/result_codes.h"
101 #include "content/public/common/url_constants.h" 103 #include "content/public/common/url_constants.h"
102 #include "content/renderer/render_process_impl.h" 104 #include "content/renderer/render_process_impl.h"
103 #include "content/renderer/render_thread_impl.h" 105 #include "content/renderer/render_thread_impl.h"
(...skipping 11 matching lines...) Expand all
115 117
116 #if defined(OS_WIN) 118 #if defined(OS_WIN)
117 #include "base/synchronization/waitable_event.h" 119 #include "base/synchronization/waitable_event.h"
118 #include "content/common/font_cache_dispatcher_win.h" 120 #include "content/common/font_cache_dispatcher_win.h"
119 #endif 121 #endif
120 122
121 #include "third_party/skia/include/core/SkBitmap.h" 123 #include "third_party/skia/include/core/SkBitmap.h"
122 124
123 extern bool g_exited_main_message_loop; 125 extern bool g_exited_main_message_loop;
124 126
127 static const char* kSiteProcessMapKeyName = "content_site_process_map";
128
125 namespace content { 129 namespace content {
126 130
127 // This class creates the IO thread for the renderer when running in 131 // This class creates the IO thread for the renderer when running in
128 // single-process mode. It's not used in multi-process mode. 132 // single-process mode. It's not used in multi-process mode.
129 class RendererMainThread : public base::Thread { 133 class RendererMainThread : public base::Thread {
130 public: 134 public:
131 explicit RendererMainThread(const std::string& channel_id) 135 explicit RendererMainThread(const std::string& channel_id)
132 : base::Thread("Chrome_InProcRendererThread"), 136 : base::Thread("Chrome_InProcRendererThread"),
133 channel_id_(channel_id), 137 channel_id_(channel_id),
134 render_process_(NULL) { 138 render_process_(NULL) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 virtual ~RendererURLRequestContextSelector() {} 205 virtual ~RendererURLRequestContextSelector() {}
202 206
203 scoped_refptr<net::URLRequestContextGetter> request_context_; 207 scoped_refptr<net::URLRequestContextGetter> request_context_;
204 scoped_refptr<net::URLRequestContextGetter> media_request_context_; 208 scoped_refptr<net::URLRequestContextGetter> media_request_context_;
205 }; 209 };
206 210
207 // the global list of all renderer processes 211 // the global list of all renderer processes
208 base::LazyInstance<IDMap<RenderProcessHost> >::Leaky 212 base::LazyInstance<IDMap<RenderProcessHost> >::Leaky
209 g_all_hosts = LAZY_INSTANCE_INITIALIZER; 213 g_all_hosts = LAZY_INSTANCE_INITIALIZER;
210 214
215 // Map of site to process, to ensure we only have one RenderProcessHost per
216 // site in process-per-site mode. Each map is specific to a BrowserContext.
217 class SiteProcessMap : public base::SupportsUserData::Data {
218 public:
219 typedef base::hash_map<std::string, RenderProcessHost*> SiteToProcessMap;
220 SiteProcessMap() {}
221
222 void RegisterProcess(std::string site, RenderProcessHost* process) {
223 map_[site] = process;
224 }
225
226 RenderProcessHost* FindProcess(std::string site) {
227 SiteToProcessMap::iterator i = map_.find(site);
228 if (i != map_.end())
229 return i->second;
230 return NULL;
231 }
232
233 void RemoveProcess(RenderProcessHost* host) {
234 // Find all instances of this process in the map, then separately remove
235 // them.
236 std::set<std::string> sites;
237 for (SiteToProcessMap::const_iterator i = map_.begin();
238 i != map_.end();
239 i++) {
240 if (i->second == host)
241 sites.insert(i->first);
242 }
243 for (std::set<std::string>::iterator i = sites.begin();
244 i != sites.end();
245 i++) {
246 SiteToProcessMap::iterator iter = map_.find(*i);
247 if (iter != map_.end()) {
248 DCHECK_EQ(iter->second, host);
249 map_.erase(iter);
250 }
251 }
252 }
253
254 private:
255 SiteToProcessMap map_;
256 };
257
258 // Find the SiteProcessMap specific to the given context.
259 SiteProcessMap* GetSiteProcessMapForBrowserContext(BrowserContext* context) {
260 DCHECK(context);
261 SiteProcessMap* map = static_cast<SiteProcessMap*>(
262 context->GetUserData(kSiteProcessMapKeyName));
263 if (!map) {
264 map = new SiteProcessMap();
265 context->SetUserData(kSiteProcessMapKeyName, map);
266 }
267 return map;
268 }
269
211 } // namespace 270 } // namespace
212 271
213 // Stores the maximum number of renderer processes the content module can 272 // Stores the maximum number of renderer processes the content module can
214 // create. 273 // create.
215 static size_t g_max_renderer_count_override = 0; 274 static size_t g_max_renderer_count_override = 0;
216 275
217 // static 276 // static
218 size_t RenderProcessHost::GetMaxRendererProcessCount() { 277 size_t RenderProcessHost::GetMaxRendererProcessCount() {
219 if (g_max_renderer_count_override) 278 if (g_max_renderer_count_override)
220 return g_max_renderer_count_override; 279 return g_max_renderer_count_override;
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 // It's important not to wait for the DeleteTask to delete the channel 1123 // It's important not to wait for the DeleteTask to delete the channel
1065 // proxy. Kill it off now. That way, in case the profile is going away, the 1124 // proxy. Kill it off now. That way, in case the profile is going away, the
1066 // rest of the objects attached to this RenderProcessHost start going 1125 // rest of the objects attached to this RenderProcessHost start going
1067 // away first, since deleting the channel proxy will post a 1126 // away first, since deleting the channel proxy will post a
1068 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread. 1127 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread.
1069 channel_.reset(); 1128 channel_.reset();
1070 gpu_message_filter_ = NULL; 1129 gpu_message_filter_ = NULL;
1071 1130
1072 // Remove ourself from the list of renderer processes so that we can't be 1131 // Remove ourself from the list of renderer processes so that we can't be
1073 // reused in between now and when the Delete task runs. 1132 // reused in between now and when the Delete task runs.
1074 g_all_hosts.Get().Remove(GetID()); 1133 UnregisterHost(GetID());
1075 } 1134 }
1076 } 1135 }
1077 1136
1078 void RenderProcessHostImpl::AddPendingView() { 1137 void RenderProcessHostImpl::AddPendingView() {
1079 pending_views_++; 1138 pending_views_++;
1080 } 1139 }
1081 1140
1082 void RenderProcessHostImpl::RemovePendingView() { 1141 void RenderProcessHostImpl::RemovePendingView() {
1083 DCHECK(pending_views_); 1142 DCHECK(pending_views_);
1084 pending_views_--; 1143 pending_views_--;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 return fast_shutdown_started_; 1183 return fast_shutdown_started_;
1125 } 1184 }
1126 1185
1127 // static 1186 // static
1128 void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) { 1187 void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) {
1129 g_all_hosts.Get().AddWithID(host, host_id); 1188 g_all_hosts.Get().AddWithID(host, host_id);
1130 } 1189 }
1131 1190
1132 // static 1191 // static
1133 void RenderProcessHostImpl::UnregisterHost(int host_id) { 1192 void RenderProcessHostImpl::UnregisterHost(int host_id) {
1134 if (g_all_hosts.Get().Lookup(host_id)) 1193 RenderProcessHost* host = g_all_hosts.Get().Lookup(host_id);
1135 g_all_hosts.Get().Remove(host_id); 1194 if (!host)
1195 return;
1196
1197 g_all_hosts.Get().Remove(host_id);
1198
1199 // Look up the map of site to process for the given browser_context,
1200 // in case we need to remove this process from it. It will be registered
1201 // under any sites it rendered that use process-per-site mode.
1202 SiteProcessMap* map =
1203 GetSiteProcessMapForBrowserContext(host->GetBrowserContext());
1204 map->RemoveProcess(host);
1136 } 1205 }
1137 1206
1138 // static 1207 // static
1139 bool RenderProcessHostImpl::IsSuitableHost( 1208 bool RenderProcessHostImpl::IsSuitableHost(
1140 RenderProcessHost* host, 1209 RenderProcessHost* host,
1141 BrowserContext* browser_context, 1210 BrowserContext* browser_context,
1142 const GURL& site_url) { 1211 const GURL& site_url) {
1143 if (run_renderer_in_process()) 1212 if (run_renderer_in_process())
1144 return true; 1213 return true;
1145 1214
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 // Now pick a random suitable renderer, if we have any. 1297 // Now pick a random suitable renderer, if we have any.
1229 if (!suitable_renderers.empty()) { 1298 if (!suitable_renderers.empty()) {
1230 int suitable_count = static_cast<int>(suitable_renderers.size()); 1299 int suitable_count = static_cast<int>(suitable_renderers.size());
1231 int random_index = base::RandInt(0, suitable_count - 1); 1300 int random_index = base::RandInt(0, suitable_count - 1);
1232 return suitable_renderers[random_index]; 1301 return suitable_renderers[random_index];
1233 } 1302 }
1234 1303
1235 return NULL; 1304 return NULL;
1236 } 1305 }
1237 1306
1307 // static
1308 bool RenderProcessHostImpl::ShouldUseProcessPerSite(
1309 BrowserContext* browser_context,
1310 const GURL& url) {
1311 // Returns true if we should use the process-per-site model. This will be
1312 // the case if the --process-per-site switch is specified, or in
1313 // process-per-site-instance for particular sites (e.g., WebUI).
1314
1315 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1316 if (command_line.HasSwitch(switches::kProcessPerSite))
1317 return true;
1318
1319 // We want to consolidate particular sites like WebUI when we are using
1320 // process-per-tab or process-per-site-instance models.
1321 // Note that --single-process is handled in ShouldTryToUseExistingProcessHost.
1322
1323 if (content::GetContentClient()->browser()->
1324 ShouldUseProcessPerSite(browser_context, url)) {
1325 return true;
1326 }
1327
1328 // DevTools pages have WebUI type but should not reuse the same host.
1329 WebUIControllerFactory* factory =
1330 content::GetContentClient()->browser()->GetWebUIControllerFactory();
1331 if (factory &&
1332 factory->UseWebUIForURL(browser_context, url) &&
1333 !url.SchemeIs(chrome::kChromeDevToolsScheme)) {
1334 return true;
1335 }
1336
1337 // In all other cases, don't use process-per-site logic.
1338 return false;
1339 }
1340
1341 // static
1342 RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSite(
1343 BrowserContext* browser_context,
1344 const GURL& url) {
1345 // Look up the map of site to process for the given browser_context.
1346 SiteProcessMap* map =
1347 GetSiteProcessMapForBrowserContext(browser_context);
1348
1349 // See if we have an existing process for this site. If not, the caller
1350 // should create a new process and register it.
1351 std::string site = SiteInstanceImpl::GetSiteForURL(browser_context, url)
1352 .possibly_invalid_spec();
1353 return map->FindProcess(site);
1354 }
1355
1356 void RenderProcessHostImpl::RegisterProcessHostForSite(
1357 BrowserContext* browser_context,
1358 RenderProcessHost* process,
1359 const GURL& url) {
1360 // Look up the map of site to process for the given browser_context.
1361 SiteProcessMap* map =
1362 GetSiteProcessMapForBrowserContext(browser_context);
1363
1364 // TODO(creis): Determine if it's better to allow registration of
1365 // empty sites or not. For now, group anything from which we can't parse
1366 // a site into the same process, when using --process-per-site.
1367 std::string site = SiteInstanceImpl::GetSiteForURL(browser_context, url)
1368 .possibly_invalid_spec();
1369 map->RegisterProcess(site, process);
1370 }
1371
1238 void RenderProcessHostImpl::ProcessDied(base::ProcessHandle handle, 1372 void RenderProcessHostImpl::ProcessDied(base::ProcessHandle handle,
1239 base::TerminationStatus status, 1373 base::TerminationStatus status,
1240 int exit_code, 1374 int exit_code,
1241 bool was_alive) { 1375 bool was_alive) {
1242 // Our child process has died. If we didn't expect it, it's a crash. 1376 // Our child process has died. If we didn't expect it, it's a crash.
1243 // In any case, we need to let everyone know it's gone. 1377 // In any case, we need to let everyone know it's gone.
1244 // The OnChannelError notification can fire multiple times due to nested sync 1378 // The OnChannelError notification can fire multiple times due to nested sync
1245 // calls to a renderer. If we don't have a valid channel here it means we 1379 // calls to a renderer. If we don't have a valid channel here it means we
1246 // already handled the error. 1380 // already handled the error.
1247 1381
1248 RendererClosedDetails details(handle, status, exit_code, was_alive); 1382 RendererClosedDetails details(handle, status, exit_code, was_alive);
1249 NotificationService::current()->Notify( 1383 NotificationService::current()->Notify(
1250 NOTIFICATION_RENDERER_PROCESS_CLOSED, 1384 NOTIFICATION_RENDERER_PROCESS_CLOSED,
1251 Source<RenderProcessHost>(this), 1385 Source<RenderProcessHost>(this),
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 uint64 surface_handle, 1525 uint64 surface_handle,
1392 int32 route_id, 1526 int32 route_id,
1393 int32 gpu_process_host_id) { 1527 int32 gpu_process_host_id) {
1394 TRACE_EVENT0("renderer_host", 1528 TRACE_EVENT0("renderer_host",
1395 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost"); 1529 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost");
1396 RenderWidgetHostImpl::AcknowledgeSwapBuffers(route_id, 1530 RenderWidgetHostImpl::AcknowledgeSwapBuffers(route_id,
1397 gpu_process_host_id); 1531 gpu_process_host_id);
1398 } 1532 }
1399 1533
1400 } // namespace content 1534 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_process_host_impl.h ('k') | content/browser/site_instance_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698