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

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: Fix review comment. 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
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..a80a142f4d7fc71b4d3bc02d8cf44419537799b1 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -35,6 +35,7 @@
#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/string_util.h"
+#include "base/supports_user_data.h"
#include "base/sys_info.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
@@ -91,6 +92,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"
@@ -122,6 +124,8 @@
extern bool g_exited_main_message_loop;
+static const char* kSiteProcessMapKeyName = "content_site_process_map";
+
namespace content {
// This class creates the IO thread for the renderer when running in
@@ -208,6 +212,61 @@ class RendererURLRequestContextSelector
base::LazyInstance<IDMap<RenderProcessHost> >::Leaky
g_all_hosts = LAZY_INSTANCE_INITIALIZER;
+// Map of site to process, to ensure we only have one RenderProcessHost per
+// site in process-per-site mode. Each map is specific to a BrowserContext.
+class SiteProcessMap : public base::SupportsUserData::Data {
+ public:
+ typedef base::hash_map<std::string, RenderProcessHost*> SiteToProcessMap;
+ SiteProcessMap() {}
+
+ void RegisterProcess(std::string site, RenderProcessHost* process) {
+ map_[site] = process;
+ }
+
+ RenderProcessHost* FindProcess(std::string site) {
+ SiteToProcessMap::iterator i = map_.find(site);
+ if (i != map_.end())
+ return i->second;
+ return NULL;
+ }
+
+ void RemoveProcess(RenderProcessHost* host) {
+ // Find all instances of this process in the map, then separately remove
+ // them.
+ std::set<std::string> sites;
+ for (SiteToProcessMap::const_iterator i = map_.begin();
+ i != map_.end();
+ i++) {
+ if (i->second == host)
+ sites.insert(i->first);
+ }
+ for (std::set<std::string>::iterator i = sites.begin();
+ i != sites.end();
+ i++) {
+ SiteToProcessMap::iterator iter = map_.find(*i);
+ if (iter != map_.end()) {
+ DCHECK_EQ(iter->second, host);
+ map_.erase(iter);
+ }
+ }
+ }
+
+ private:
+ SiteToProcessMap map_;
+};
+
+// Find the SiteProcessMap specific to the given context.
+SiteProcessMap* GetSiteProcessMapForBrowserContext(BrowserContext* context) {
+ DCHECK(context);
+ SiteProcessMap* map = static_cast<SiteProcessMap*>(
+ context->GetUserData(kSiteProcessMapKeyName));
+ if (!map) {
+ map = new SiteProcessMap();
+ context->SetUserData(kSiteProcessMapKeyName, map);
+ }
+ return map;
+}
+
} // namespace
// Stores the maximum number of renderer processes the content module can
@@ -1071,7 +1130,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());
}
}
@@ -1131,8 +1190,18 @@ void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) {
// static
void RenderProcessHostImpl::UnregisterHost(int host_id) {
- if (g_all_hosts.Get().Lookup(host_id))
- g_all_hosts.Get().Remove(host_id);
+ RenderProcessHost* host = g_all_hosts.Get().Lookup(host_id);
+ if (!host)
+ return;
+
+ 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.
+ SiteProcessMap* map =
+ GetSiteProcessMapForBrowserContext(host->GetBrowserContext());
+ map->RemoveProcess(host);
}
// static
@@ -1235,10 +1304,75 @@ RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
return NULL;
}
+// static
+bool RenderProcessHostImpl::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* RenderProcessHostImpl::GetProcessHostForSite(
+ BrowserContext* browser_context,
+ const GURL& url) {
+ // Look up the map of site to process for the given browser_context.
+ SiteProcessMap* map =
+ GetSiteProcessMapForBrowserContext(browser_context);
+
+ // See if we have an existing process for this site. If not, the caller
+ // should create a new process and register it.
+ std::string site = SiteInstanceImpl::GetSiteForURL(browser_context, url)
+ .possibly_invalid_spec();
+ return map->FindProcess(site);
+}
+
+void RenderProcessHostImpl::RegisterProcessHostForSite(
+ BrowserContext* browser_context,
+ RenderProcessHost* process,
+ const GURL& url) {
+ // Look up the map of site to process for the given browser_context.
+ SiteProcessMap* map =
+ GetSiteProcessMapForBrowserContext(browser_context);
+
+ // TODO(creis): Determine if it's better to allow registration of
+ // empty sites or not. For now, group anything from which we can't parse
+ // a site into the same process, when using --process-per-site.
+ std::string site = SiteInstanceImpl::GetSiteForURL(browser_context, url)
+ .possibly_invalid_spec();
+ map->RegisterProcess(site, process);
+}
+
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
« 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