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 // 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 #include "content/browser/trace_message_filter.h" | 84 #include "content/browser/trace_message_filter.h" |
| 85 #include "content/browser/worker_host/worker_message_filter.h" | 85 #include "content/browser/worker_host/worker_message_filter.h" |
| 86 #include "content/common/child_process_host_impl.h" | 86 #include "content/common/child_process_host_impl.h" |
| 87 #include "content/common/child_process_messages.h" | 87 #include "content/common/child_process_messages.h" |
| 88 #include "content/common/gpu/gpu_messages.h" | 88 #include "content/common/gpu/gpu_messages.h" |
| 89 #include "content/common/resource_messages.h" | 89 #include "content/common/resource_messages.h" |
| 90 #include "content/common/view_messages.h" | 90 #include "content/common/view_messages.h" |
| 91 #include "content/public/browser/browser_context.h" | 91 #include "content/public/browser/browser_context.h" |
| 92 #include "content/public/browser/content_browser_client.h" | 92 #include "content/public/browser/content_browser_client.h" |
| 93 #include "content/public/browser/notification_service.h" | 93 #include "content/public/browser/notification_service.h" |
| 94 #include "content/public/browser/render_process_host_factory.h" | |
| 94 #include "content/public/browser/resource_context.h" | 95 #include "content/public/browser/resource_context.h" |
| 95 #include "content/public/browser/user_metrics.h" | 96 #include "content/public/browser/user_metrics.h" |
| 96 #include "content/public/browser/web_ui_controller_factory.h" | 97 #include "content/public/browser/web_ui_controller_factory.h" |
| 97 #include "content/public/common/content_constants.h" | 98 #include "content/public/common/content_constants.h" |
| 98 #include "content/public/common/content_switches.h" | 99 #include "content/public/common/content_switches.h" |
| 99 #include "content/public/common/process_type.h" | 100 #include "content/public/common/process_type.h" |
| 100 #include "content/public/common/result_codes.h" | 101 #include "content/public/common/result_codes.h" |
| 101 #include "content/public/common/url_constants.h" | 102 #include "content/public/common/url_constants.h" |
| 102 #include "content/renderer/render_process_impl.h" | 103 #include "content/renderer/render_process_impl.h" |
| 103 #include "content/renderer/render_thread_impl.h" | 104 #include "content/renderer/render_thread_impl.h" |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 virtual ~RendererURLRequestContextSelector() {} | 202 virtual ~RendererURLRequestContextSelector() {} |
| 202 | 203 |
| 203 scoped_refptr<net::URLRequestContextGetter> request_context_; | 204 scoped_refptr<net::URLRequestContextGetter> request_context_; |
| 204 scoped_refptr<net::URLRequestContextGetter> media_request_context_; | 205 scoped_refptr<net::URLRequestContextGetter> media_request_context_; |
| 205 }; | 206 }; |
| 206 | 207 |
| 207 // the global list of all renderer processes | 208 // the global list of all renderer processes |
| 208 base::LazyInstance<IDMap<RenderProcessHost> >::Leaky | 209 base::LazyInstance<IDMap<RenderProcessHost> >::Leaky |
| 209 g_all_hosts = LAZY_INSTANCE_INITIALIZER; | 210 g_all_hosts = LAZY_INSTANCE_INITIALIZER; |
| 210 | 211 |
| 212 // The global map of BrowsingContexts to SiteProcessMaps, allowing us to | |
| 213 // implement process-per-site mode within each BrowsingContext. | |
| 214 base::LazyInstance<RenderProcessHostImpl::ContextSiteProcessMap>::Leaky | |
| 215 g_context_site_process_map_ = LAZY_INSTANCE_INITIALIZER; | |
| 216 | |
| 211 } // namespace | 217 } // namespace |
| 212 | 218 |
| 213 // Stores the maximum number of renderer processes the content module can | 219 // Stores the maximum number of renderer processes the content module can |
| 214 // create. | 220 // create. |
| 215 static size_t g_max_renderer_count_override = 0; | 221 static size_t g_max_renderer_count_override = 0; |
| 216 | 222 |
| 217 // static | 223 // static |
| 218 size_t RenderProcessHost::GetMaxRendererProcessCount() { | 224 size_t RenderProcessHost::GetMaxRendererProcessCount() { |
| 219 if (g_max_renderer_count_override) | 225 if (g_max_renderer_count_override) |
| 220 return g_max_renderer_count_override; | 226 return g_max_renderer_count_override; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID()); | 337 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID()); |
| 332 | 338 |
| 333 // We may have some unsent messages at this point, but that's OK. | 339 // We may have some unsent messages at this point, but that's OK. |
| 334 channel_.reset(); | 340 channel_.reset(); |
| 335 while (!queued_messages_.empty()) { | 341 while (!queued_messages_.empty()) { |
| 336 delete queued_messages_.front(); | 342 delete queued_messages_.front(); |
| 337 queued_messages_.pop(); | 343 queued_messages_.pop(); |
| 338 } | 344 } |
| 339 | 345 |
| 340 ClearTransportDIBCache(); | 346 ClearTransportDIBCache(); |
| 341 UnregisterHost(GetID()); | 347 UnregisterHost(GetID(), this); |
| 342 } | 348 } |
| 343 | 349 |
| 344 void RenderProcessHostImpl::EnableSendQueue() { | 350 void RenderProcessHostImpl::EnableSendQueue() { |
| 345 is_initialized_ = false; | 351 is_initialized_ = false; |
| 346 } | 352 } |
| 347 | 353 |
| 348 bool RenderProcessHostImpl::Init() { | 354 bool RenderProcessHostImpl::Init() { |
| 349 // calling Init() more than once does nothing, this makes it more convenient | 355 // calling Init() more than once does nothing, this makes it more convenient |
| 350 // for the view host which may not be sure in some cases | 356 // for the view host which may not be sure in some cases |
| 351 if (channel_.get()) | 357 if (channel_.get()) |
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1064 // It's important not to wait for the DeleteTask to delete the channel | 1070 // 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 | 1071 // 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 | 1072 // rest of the objects attached to this RenderProcessHost start going |
| 1067 // away first, since deleting the channel proxy will post a | 1073 // away first, since deleting the channel proxy will post a |
| 1068 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread. | 1074 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread. |
| 1069 channel_.reset(); | 1075 channel_.reset(); |
| 1070 gpu_message_filter_ = NULL; | 1076 gpu_message_filter_ = NULL; |
| 1071 | 1077 |
| 1072 // Remove ourself from the list of renderer processes so that we can't be | 1078 // 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. | 1079 // reused in between now and when the Delete task runs. |
| 1074 g_all_hosts.Get().Remove(GetID()); | 1080 UnregisterHost(GetID(), this); |
| 1075 } | 1081 } |
| 1076 } | 1082 } |
| 1077 | 1083 |
| 1078 void RenderProcessHostImpl::AddPendingView() { | 1084 void RenderProcessHostImpl::AddPendingView() { |
| 1079 pending_views_++; | 1085 pending_views_++; |
| 1080 } | 1086 } |
| 1081 | 1087 |
| 1082 void RenderProcessHostImpl::RemovePendingView() { | 1088 void RenderProcessHostImpl::RemovePendingView() { |
| 1083 DCHECK(pending_views_); | 1089 DCHECK(pending_views_); |
| 1084 pending_views_--; | 1090 pending_views_--; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1123 bool RenderProcessHostImpl::FastShutdownStarted() const { | 1129 bool RenderProcessHostImpl::FastShutdownStarted() const { |
| 1124 return fast_shutdown_started_; | 1130 return fast_shutdown_started_; |
| 1125 } | 1131 } |
| 1126 | 1132 |
| 1127 // static | 1133 // static |
| 1128 void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) { | 1134 void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) { |
| 1129 g_all_hosts.Get().AddWithID(host, host_id); | 1135 g_all_hosts.Get().AddWithID(host, host_id); |
| 1130 } | 1136 } |
| 1131 | 1137 |
| 1132 // static | 1138 // static |
| 1133 void RenderProcessHostImpl::UnregisterHost(int host_id) { | 1139 void RenderProcessHostImpl::UnregisterHost(int host_id, |
| 1140 RenderProcessHost* host) { | |
| 1134 if (g_all_hosts.Get().Lookup(host_id)) | 1141 if (g_all_hosts.Get().Lookup(host_id)) |
| 1135 g_all_hosts.Get().Remove(host_id); | 1142 g_all_hosts.Get().Remove(host_id); |
| 1143 | |
| 1144 // Look up the map of site to process for the given browser_context, | |
| 1145 // in case we need to remove this process from it. It will be registered | |
| 1146 // under any sites it rendered that use process-per-site mode. | |
| 1147 RenderProcessHostImpl::SiteProcessMap* map = | |
| 1148 &g_context_site_process_map_.Get()[host->GetBrowserContext()]; | |
|
awong
2012/06/27 00:26:54
Having a global map of BrowserContext objects -> d
Charlie Reis
2012/06/27 20:53:43
That would be possible, but it also requires addin
awong
2012/06/27 21:24:40
sgtm
| |
| 1149 // Find all instances of this process in the map, to remove. | |
| 1150 std::set<std::string> sites; | |
| 1151 for (RenderProcessHostImpl::SiteProcessMap::const_iterator i = map->begin(); | |
| 1152 i != map->end(); | |
| 1153 i++) { | |
| 1154 if (i->second == host) | |
| 1155 sites.insert(i->first); | |
| 1156 } | |
| 1157 // Remove them from the map. | |
|
awong
2012/06/27 00:26:54
I'd just merge this with the previous comment. Thi
Charlie Reis
2012/06/27 20:53:43
Done.
| |
| 1158 for (std::set<std::string>::iterator i = sites.begin(); | |
| 1159 i != sites.end(); | |
| 1160 i++) { | |
| 1161 RenderProcessHostImpl::SiteProcessMap::iterator iter = map->find(*i); | |
| 1162 if (iter != map->end()) { | |
| 1163 DCHECK_EQ(iter->second, host); | |
| 1164 map->erase(iter); | |
| 1165 } | |
| 1166 } | |
| 1136 } | 1167 } |
| 1137 | 1168 |
| 1138 // static | 1169 // static |
| 1139 bool RenderProcessHostImpl::IsSuitableHost( | 1170 bool RenderProcessHostImpl::IsSuitableHost( |
| 1140 RenderProcessHost* host, | 1171 RenderProcessHost* host, |
| 1141 BrowserContext* browser_context, | 1172 BrowserContext* browser_context, |
| 1142 const GURL& site_url) { | 1173 const GURL& site_url) { |
| 1143 if (run_renderer_in_process()) | 1174 if (run_renderer_in_process()) |
| 1144 return true; | 1175 return true; |
| 1145 | 1176 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1228 // Now pick a random suitable renderer, if we have any. | 1259 // Now pick a random suitable renderer, if we have any. |
| 1229 if (!suitable_renderers.empty()) { | 1260 if (!suitable_renderers.empty()) { |
| 1230 int suitable_count = static_cast<int>(suitable_renderers.size()); | 1261 int suitable_count = static_cast<int>(suitable_renderers.size()); |
| 1231 int random_index = base::RandInt(0, suitable_count - 1); | 1262 int random_index = base::RandInt(0, suitable_count - 1); |
| 1232 return suitable_renderers[random_index]; | 1263 return suitable_renderers[random_index]; |
| 1233 } | 1264 } |
| 1234 | 1265 |
| 1235 return NULL; | 1266 return NULL; |
| 1236 } | 1267 } |
| 1237 | 1268 |
| 1269 // static | |
| 1270 bool RenderProcessHost::ShouldUseProcessPerSite(BrowserContext* browser_context, | |
| 1271 const GURL& url) { | |
| 1272 // Returns true if we should use the process-per-site model. This will be | |
| 1273 // the case if the --process-per-site switch is specified, or in | |
| 1274 // process-per-site-instance for particular sites (e.g., WebUI). | |
| 1275 | |
| 1276 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
| 1277 if (command_line.HasSwitch(switches::kProcessPerSite)) | |
| 1278 return true; | |
| 1279 | |
| 1280 // We want to consolidate particular sites like WebUI when we are using | |
| 1281 // process-per-tab or process-per-site-instance models. | |
| 1282 // Note that --single-process is handled in ShouldTryToUseExistingProcessHost. | |
| 1283 | |
| 1284 if (content::GetContentClient()->browser()-> | |
| 1285 ShouldUseProcessPerSite(browser_context, url)) { | |
| 1286 return true; | |
| 1287 } | |
| 1288 | |
| 1289 // DevTools pages have WebUI type but should not reuse the same host. | |
| 1290 WebUIControllerFactory* factory = | |
| 1291 content::GetContentClient()->browser()->GetWebUIControllerFactory(); | |
| 1292 if (factory && | |
| 1293 factory->UseWebUIForURL(browser_context, url) && | |
| 1294 !url.SchemeIs(chrome::kChromeDevToolsScheme)) { | |
| 1295 return true; | |
| 1296 } | |
| 1297 | |
| 1298 // In all other cases, don't use process-per-site logic. | |
| 1299 return false; | |
| 1300 } | |
| 1301 | |
| 1302 // static | |
| 1303 RenderProcessHost* RenderProcessHost::GetProcessHostForSite( | |
| 1304 BrowserContext* browser_context, | |
| 1305 const GURL& url) { | |
| 1306 // Look up the map of site to process for the given browser_context. | |
| 1307 RenderProcessHostImpl::SiteProcessMap* map = | |
| 1308 &g_context_site_process_map_.Get()[browser_context]; | |
| 1309 | |
| 1310 // See if we have an existing process for this site. | |
| 1311 GURL site_url = SiteInstanceImpl::GetSiteForURL(browser_context, url); | |
|
awong
2012/06/27 00:26:54
std::string site = SiteInstanceImpl::GetSiteForURL
Charlie Reis
2012/06/27 20:53:43
Done.
| |
| 1312 std::string site = site_url.possibly_invalid_spec(); | |
| 1313 RenderProcessHostImpl::SiteProcessMap::iterator i = map->find(site); | |
| 1314 if (i != map->end()) | |
| 1315 return i->second; | |
| 1316 | |
| 1317 // Otherwise, the caller should create a new process and register it. | |
| 1318 return NULL; | |
| 1319 } | |
| 1320 | |
| 1321 void RenderProcessHost::RegisterProcessHostForSite( | |
| 1322 BrowserContext* browser_context, | |
| 1323 RenderProcessHost* process, | |
| 1324 const GURL& url) { | |
| 1325 // Look up the map of site to process for the given browser_context. | |
| 1326 RenderProcessHostImpl::SiteProcessMap* map = | |
| 1327 &g_context_site_process_map_.Get()[browser_context]; | |
| 1328 | |
| 1329 GURL site_url = SiteInstanceImpl::GetSiteForURL(browser_context, url); | |
| 1330 std::string site = site_url.possibly_invalid_spec(); | |
| 1331 if (!site.empty()) | |
| 1332 (*map)[site] = process; | |
|
awong
2012/06/27 00:26:54
What happens if the site is empty? The process is
Charlie Reis
2012/06/27 20:53:43
Right. I didn't think we would want to group all
awong
2012/06/27 21:24:40
Cool. Also maybe a comment explaining why the beh
Charlie Reis
2012/06/27 21:42:30
Not sure there's a clear answer, so I added a TODO
| |
| 1333 } | |
| 1334 | |
| 1238 void RenderProcessHostImpl::ProcessDied(base::ProcessHandle handle, | 1335 void RenderProcessHostImpl::ProcessDied(base::ProcessHandle handle, |
| 1239 base::TerminationStatus status, | 1336 base::TerminationStatus status, |
| 1240 int exit_code, | 1337 int exit_code, |
| 1241 bool was_alive) { | 1338 bool was_alive) { |
| 1242 // Our child process has died. If we didn't expect it, it's a crash. | 1339 // 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. | 1340 // In any case, we need to let everyone know it's gone. |
| 1244 // The OnChannelError notification can fire multiple times due to nested sync | 1341 // 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 | 1342 // calls to a renderer. If we don't have a valid channel here it means we |
| 1246 // already handled the error. | 1343 // already handled the error. |
| 1247 | 1344 |
| 1248 RendererClosedDetails details(handle, status, exit_code, was_alive); | 1345 RendererClosedDetails details(handle, status, exit_code, was_alive); |
| 1249 NotificationService::current()->Notify( | 1346 NotificationService::current()->Notify( |
| 1250 NOTIFICATION_RENDERER_PROCESS_CLOSED, | 1347 NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 1251 Source<RenderProcessHost>(this), | 1348 Source<RenderProcessHost>(this), |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1391 uint64 surface_handle, | 1488 uint64 surface_handle, |
| 1392 int32 route_id, | 1489 int32 route_id, |
| 1393 int32 gpu_process_host_id) { | 1490 int32 gpu_process_host_id) { |
| 1394 TRACE_EVENT0("renderer_host", | 1491 TRACE_EVENT0("renderer_host", |
| 1395 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost"); | 1492 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost"); |
| 1396 RenderWidgetHostImpl::AcknowledgeSwapBuffers(route_id, | 1493 RenderWidgetHostImpl::AcknowledgeSwapBuffers(route_id, |
| 1397 gpu_process_host_id); | 1494 gpu_process_host_id); |
| 1398 } | 1495 } |
| 1399 | 1496 |
| 1400 } // namespace content | 1497 } // namespace content |
| OLD | NEW |