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()]; |
| 1149 // Find all instances of this process in the map, then separately remove them. |
| 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 for (std::set<std::string>::iterator i = sites.begin(); |
| 1158 i != sites.end(); |
| 1159 i++) { |
| 1160 RenderProcessHostImpl::SiteProcessMap::iterator iter = map->find(*i); |
| 1161 if (iter != map->end()) { |
| 1162 DCHECK_EQ(iter->second, host); |
| 1163 map->erase(iter); |
| 1164 } |
| 1165 } |
1136 } | 1166 } |
1137 | 1167 |
1138 // static | 1168 // static |
1139 bool RenderProcessHostImpl::IsSuitableHost( | 1169 bool RenderProcessHostImpl::IsSuitableHost( |
1140 RenderProcessHost* host, | 1170 RenderProcessHost* host, |
1141 BrowserContext* browser_context, | 1171 BrowserContext* browser_context, |
1142 const GURL& site_url) { | 1172 const GURL& site_url) { |
1143 if (run_renderer_in_process()) | 1173 if (run_renderer_in_process()) |
1144 return true; | 1174 return true; |
1145 | 1175 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 // Now pick a random suitable renderer, if we have any. | 1258 // Now pick a random suitable renderer, if we have any. |
1229 if (!suitable_renderers.empty()) { | 1259 if (!suitable_renderers.empty()) { |
1230 int suitable_count = static_cast<int>(suitable_renderers.size()); | 1260 int suitable_count = static_cast<int>(suitable_renderers.size()); |
1231 int random_index = base::RandInt(0, suitable_count - 1); | 1261 int random_index = base::RandInt(0, suitable_count - 1); |
1232 return suitable_renderers[random_index]; | 1262 return suitable_renderers[random_index]; |
1233 } | 1263 } |
1234 | 1264 |
1235 return NULL; | 1265 return NULL; |
1236 } | 1266 } |
1237 | 1267 |
| 1268 // static |
| 1269 bool RenderProcessHost::ShouldUseProcessPerSite(BrowserContext* browser_context, |
| 1270 const GURL& url) { |
| 1271 // Returns true if we should use the process-per-site model. This will be |
| 1272 // the case if the --process-per-site switch is specified, or in |
| 1273 // process-per-site-instance for particular sites (e.g., WebUI). |
| 1274 |
| 1275 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 1276 if (command_line.HasSwitch(switches::kProcessPerSite)) |
| 1277 return true; |
| 1278 |
| 1279 // We want to consolidate particular sites like WebUI when we are using |
| 1280 // process-per-tab or process-per-site-instance models. |
| 1281 // Note that --single-process is handled in ShouldTryToUseExistingProcessHost. |
| 1282 |
| 1283 if (content::GetContentClient()->browser()-> |
| 1284 ShouldUseProcessPerSite(browser_context, url)) { |
| 1285 return true; |
| 1286 } |
| 1287 |
| 1288 // DevTools pages have WebUI type but should not reuse the same host. |
| 1289 WebUIControllerFactory* factory = |
| 1290 content::GetContentClient()->browser()->GetWebUIControllerFactory(); |
| 1291 if (factory && |
| 1292 factory->UseWebUIForURL(browser_context, url) && |
| 1293 !url.SchemeIs(chrome::kChromeDevToolsScheme)) { |
| 1294 return true; |
| 1295 } |
| 1296 |
| 1297 // In all other cases, don't use process-per-site logic. |
| 1298 return false; |
| 1299 } |
| 1300 |
| 1301 // static |
| 1302 RenderProcessHost* RenderProcessHost::GetProcessHostForSite( |
| 1303 BrowserContext* browser_context, |
| 1304 const GURL& url) { |
| 1305 // Look up the map of site to process for the given browser_context. |
| 1306 RenderProcessHostImpl::SiteProcessMap* map = |
| 1307 &g_context_site_process_map_.Get()[browser_context]; |
| 1308 |
| 1309 // See if we have an existing process for this site. |
| 1310 std::string site = SiteInstanceImpl::GetSiteForURL(browser_context, url) |
| 1311 .possibly_invalid_spec(); |
| 1312 RenderProcessHostImpl::SiteProcessMap::iterator i = map->find(site); |
| 1313 if (i != map->end()) |
| 1314 return i->second; |
| 1315 |
| 1316 // Otherwise, the caller should create a new process and register it. |
| 1317 return NULL; |
| 1318 } |
| 1319 |
| 1320 void RenderProcessHost::RegisterProcessHostForSite( |
| 1321 BrowserContext* browser_context, |
| 1322 RenderProcessHost* process, |
| 1323 const GURL& url) { |
| 1324 // Look up the map of site to process for the given browser_context. |
| 1325 RenderProcessHostImpl::SiteProcessMap* map = |
| 1326 &g_context_site_process_map_.Get()[browser_context]; |
| 1327 |
| 1328 // TODO(creis): Determine if it's better to allow registration of |
| 1329 // empty sites or not. For now, group anything from which we can't parse |
| 1330 // a site into the same process, when using --process-per-site. |
| 1331 std::string site = SiteInstanceImpl::GetSiteForURL(browser_context, url) |
| 1332 .possibly_invalid_spec(); |
| 1333 (*map)[site] = process; |
| 1334 } |
| 1335 |
1238 void RenderProcessHostImpl::ProcessDied(base::ProcessHandle handle, | 1336 void RenderProcessHostImpl::ProcessDied(base::ProcessHandle handle, |
1239 base::TerminationStatus status, | 1337 base::TerminationStatus status, |
1240 int exit_code, | 1338 int exit_code, |
1241 bool was_alive) { | 1339 bool was_alive) { |
1242 // Our child process has died. If we didn't expect it, it's a crash. | 1340 // 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. | 1341 // In any case, we need to let everyone know it's gone. |
1244 // The OnChannelError notification can fire multiple times due to nested sync | 1342 // 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 | 1343 // calls to a renderer. If we don't have a valid channel here it means we |
1246 // already handled the error. | 1344 // already handled the error. |
1247 | 1345 |
1248 RendererClosedDetails details(handle, status, exit_code, was_alive); | 1346 RendererClosedDetails details(handle, status, exit_code, was_alive); |
1249 NotificationService::current()->Notify( | 1347 NotificationService::current()->Notify( |
1250 NOTIFICATION_RENDERER_PROCESS_CLOSED, | 1348 NOTIFICATION_RENDERER_PROCESS_CLOSED, |
1251 Source<RenderProcessHost>(this), | 1349 Source<RenderProcessHost>(this), |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1391 uint64 surface_handle, | 1489 uint64 surface_handle, |
1392 int32 route_id, | 1490 int32 route_id, |
1393 int32 gpu_process_host_id) { | 1491 int32 gpu_process_host_id) { |
1394 TRACE_EVENT0("renderer_host", | 1492 TRACE_EVENT0("renderer_host", |
1395 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost"); | 1493 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost"); |
1396 RenderWidgetHostImpl::AcknowledgeSwapBuffers(route_id, | 1494 RenderWidgetHostImpl::AcknowledgeSwapBuffers(route_id, |
1397 gpu_process_host_id); | 1495 gpu_process_host_id); |
1398 } | 1496 } |
1399 | 1497 |
1400 } // namespace content | 1498 } // namespace content |
OLD | NEW |