blob: 096e6d5ee5ea5b9ffb7de7494146195116d716c0 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/browsing_instance.h"
6
7#include "base/command_line.h"
[email protected]f3ec7742009-01-15 00:59:168#include "chrome/browser/tab_contents/site_instance.h"
initial.commit09911bf2008-07-26 23:55:299#include "chrome/common/chrome_switches.h"
[email protected]dcf7d352009-02-26 01:56:0210#include "chrome/common/url_constants.h"
initial.commit09911bf2008-07-26 23:55:2911
12/*static*/
13BrowsingInstance::ProfileSiteInstanceMap
14 BrowsingInstance::profile_site_instance_map_;
15
16bool BrowsingInstance::ShouldUseProcessPerSite(const GURL& url) {
17 // Returns true if we should use the process-per-site model. This will be
18 // the case if the --process-per-site switch is specified, or in
19 // process-per-site-instance for particular sites (e.g., the new tab page).
20
[email protected]bb975362009-01-21 01:00:2221 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
22 if (command_line.HasSwitch(switches::kProcessPerSite))
initial.commit09911bf2008-07-26 23:55:2923 return true;
24
[email protected]bb975362009-01-21 01:00:2225 if (!command_line.HasSwitch(switches::kProcessPerTab)) {
initial.commit09911bf2008-07-26 23:55:2926 // We are not in process-per-site or process-per-tab, so we must be in the
27 // default (process-per-site-instance). Only use the process-per-site
28 // logic for particular sites that we want to consolidate.
29 // Note that --single-process may have been specified, but that affects the
30 // process creation logic in RenderProcessHost, so we do not need to worry
31 // about it here.
[email protected]69f1be82009-04-16 22:27:2132 if (url.SchemeIs(chrome::kChromeUIScheme) ||
33 url.SchemeIs(chrome::kExtensionScheme))
initial.commit09911bf2008-07-26 23:55:2934 // Always consolidate instances of the new tab page (and instances of any
[email protected]69f1be82009-04-16 22:27:2135 // other internal resource urls), as well as extensions.
initial.commit09911bf2008-07-26 23:55:2936 return true;
37
38 // TODO(creis): List any other special cases that we want to limit to a
39 // single process for all instances.
40 }
41
42 // In all other cases, don't use process-per-site logic.
43 return false;
44}
45
46BrowsingInstance::SiteInstanceMap* BrowsingInstance::GetSiteInstanceMap(
47 Profile* profile, const GURL& url) {
48 if (!ShouldUseProcessPerSite(url)) {
49 // Not using process-per-site, so use a map specific to this instance.
50 return &site_instance_map_;
51 }
52
53 // Otherwise, process-per-site is in use, at least for this URL. Look up the
54 // global map for this profile, creating an entry if necessary.
55 return &profile_site_instance_map_[profile];
56}
57
58bool BrowsingInstance::HasSiteInstance(const GURL& url) {
59 std::string site = SiteInstance::GetSiteForURL(url).possibly_invalid_spec();
60
61 SiteInstanceMap* map = GetSiteInstanceMap(profile_, url);
62 SiteInstanceMap::iterator i = map->find(site);
63 return (i != map->end());
64}
65
66SiteInstance* BrowsingInstance::GetSiteInstanceForURL(const GURL& url) {
67 std::string site = SiteInstance::GetSiteForURL(url).possibly_invalid_spec();
68
69 SiteInstanceMap* map = GetSiteInstanceMap(profile_, url);
70 SiteInstanceMap::iterator i = map->find(site);
71 if (i != map->end()) {
72 return i->second;
73 }
74
75 // No current SiteInstance for this site, so let's create one.
76 SiteInstance* instance = new SiteInstance(this);
77
78 // Set the site of this new SiteInstance, which will register it with us.
79 instance->SetSite(url);
80 return instance;
81}
82
83void BrowsingInstance::RegisterSiteInstance(SiteInstance* site_instance) {
84 DCHECK(site_instance->browsing_instance() == this);
85 DCHECK(site_instance->has_site());
86 std::string site = site_instance->site().possibly_invalid_spec();
87
88 // Only register if we don't have a SiteInstance for this site already.
89 // It's possible to have two SiteInstances point to the same site if two
90 // tabs are navigated there at the same time. (We don't call SetSite or
91 // register them until DidNavigate.) If there is a previously existing
92 // SiteInstance for this site, we just won't register the new one.
93 SiteInstanceMap* map = GetSiteInstanceMap(profile_, site_instance->site());
94 SiteInstanceMap::iterator i = map->find(site);
95 if (i == map->end()) {
96 // Not previously registered, so register it.
97 (*map)[site] = site_instance;
98 }
99}
100
101void BrowsingInstance::UnregisterSiteInstance(SiteInstance* site_instance) {
102 DCHECK(site_instance->browsing_instance() == this);
103 DCHECK(site_instance->has_site());
104 std::string site = site_instance->site().possibly_invalid_spec();
105
106 // Only unregister the SiteInstance if it is the same one that is registered
107 // for the site. (It might have been an unregistered SiteInstance. See the
108 // comments in RegisterSiteInstance.)
109 SiteInstanceMap* map = GetSiteInstanceMap(profile_, site_instance->site());
110 SiteInstanceMap::iterator i = map->find(site);
111 if (i != map->end() && i->second == site_instance) {
112 // Matches, so erase it.
113 map->erase(i);
114 }
115}