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

Unified 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: Clean up RPHs in test. Created 8 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/render_process_host_impl.cc
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 8e759337fd632a9af30667f8d2ec36c1a8890b58..f309f9adfe228d2f5ebef616257128e097996ab9 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -91,6 +91,7 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_service.h"
+#include "content/public/browser/render_process_host_factory.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_ui_controller_factory.h"
@@ -208,6 +209,11 @@ class RendererURLRequestContextSelector
base::LazyInstance<IDMap<RenderProcessHost> >::Leaky
g_all_hosts = LAZY_INSTANCE_INITIALIZER;
+// The global map of BrowsingContexts to SiteProcessMaps, allowing us to
+// implement process-per-site mode within each BrowsingContext.
+base::LazyInstance<RenderProcessHostImpl::ContextSiteProcessMap>::Leaky
+ g_context_site_process_map_ = LAZY_INSTANCE_INITIALIZER;
+
} // namespace
// Stores the maximum number of renderer processes the content module can
@@ -338,7 +344,7 @@ RenderProcessHostImpl::~RenderProcessHostImpl() {
}
ClearTransportDIBCache();
- UnregisterHost(GetID());
+ UnregisterHost(GetID(), this);
}
void RenderProcessHostImpl::EnableSendQueue() {
@@ -1071,7 +1077,7 @@ void RenderProcessHostImpl::Cleanup() {
// Remove ourself from the list of renderer processes so that we can't be
// reused in between now and when the Delete task runs.
- g_all_hosts.Get().Remove(GetID());
+ UnregisterHost(GetID(), this);
}
}
@@ -1130,9 +1136,34 @@ void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) {
}
// static
-void RenderProcessHostImpl::UnregisterHost(int host_id) {
+void RenderProcessHostImpl::UnregisterHost(int host_id,
+ RenderProcessHost* host) {
if (g_all_hosts.Get().Lookup(host_id))
g_all_hosts.Get().Remove(host_id);
+
+ // Look up the map of site to process for the given browser_context,
+ // in case we need to remove this process from it. It will be registered
+ // under any sites it rendered that use process-per-site mode.
+ RenderProcessHostImpl::SiteProcessMap* map =
+ &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
+ // Find all instances of this process in the map, to remove.
+ std::set<std::string> sites;
+ for (RenderProcessHostImpl::SiteProcessMap::const_iterator i = map->begin();
+ i != map->end();
+ i++) {
+ if (i->second == host)
+ sites.insert(i->first);
+ }
+ // 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.
+ for (std::set<std::string>::iterator i = sites.begin();
+ i != sites.end();
+ i++) {
+ RenderProcessHostImpl::SiteProcessMap::iterator iter = map->find(*i);
+ if (iter != map->end()) {
+ DCHECK_EQ(iter->second, host);
+ map->erase(iter);
+ }
+ }
}
// static
@@ -1235,10 +1266,76 @@ RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
return NULL;
}
+// static
+bool RenderProcessHost::ShouldUseProcessPerSite(BrowserContext* browser_context,
+ const GURL& url) {
+ // Returns true if we should use the process-per-site model. This will be
+ // the case if the --process-per-site switch is specified, or in
+ // process-per-site-instance for particular sites (e.g., WebUI).
+
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kProcessPerSite))
+ return true;
+
+ // We want to consolidate particular sites like WebUI when we are using
+ // process-per-tab or process-per-site-instance models.
+ // Note that --single-process is handled in ShouldTryToUseExistingProcessHost.
+
+ if (content::GetContentClient()->browser()->
+ ShouldUseProcessPerSite(browser_context, url)) {
+ return true;
+ }
+
+ // DevTools pages have WebUI type but should not reuse the same host.
+ WebUIControllerFactory* factory =
+ content::GetContentClient()->browser()->GetWebUIControllerFactory();
+ if (factory &&
+ factory->UseWebUIForURL(browser_context, url) &&
+ !url.SchemeIs(chrome::kChromeDevToolsScheme)) {
+ return true;
+ }
+
+ // In all other cases, don't use process-per-site logic.
+ return false;
+}
+
+// static
+RenderProcessHost* RenderProcessHost::GetProcessHostForSite(
+ BrowserContext* browser_context,
+ const GURL& url) {
+ // Look up the map of site to process for the given browser_context.
+ RenderProcessHostImpl::SiteProcessMap* map =
+ &g_context_site_process_map_.Get()[browser_context];
+
+ // See if we have an existing process for this site.
+ 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.
+ std::string site = site_url.possibly_invalid_spec();
+ RenderProcessHostImpl::SiteProcessMap::iterator i = map->find(site);
+ if (i != map->end())
+ return i->second;
+
+ // Otherwise, the caller should create a new process and register it.
+ return NULL;
+}
+
+void RenderProcessHost::RegisterProcessHostForSite(
+ BrowserContext* browser_context,
+ RenderProcessHost* process,
+ const GURL& url) {
+ // Look up the map of site to process for the given browser_context.
+ RenderProcessHostImpl::SiteProcessMap* map =
+ &g_context_site_process_map_.Get()[browser_context];
+
+ GURL site_url = SiteInstanceImpl::GetSiteForURL(browser_context, url);
+ std::string site = site_url.possibly_invalid_spec();
+ if (!site.empty())
+ (*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
+}
+
void RenderProcessHostImpl::ProcessDied(base::ProcessHandle handle,
- base::TerminationStatus status,
- int exit_code,
- bool was_alive) {
+ base::TerminationStatus status,
+ int exit_code,
+ bool was_alive) {
// Our child process has died. If we didn't expect it, it's a crash.
// In any case, we need to let everyone know it's gone.
// The OnChannelError notification can fire multiple times due to nested sync

Powered by Google App Engine
This is Rietveld 408576698