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 |