|
@@ -64,7 +64,16 @@ bool g_suppress_renderer_process_restart = false;
|
|
|
// Custom schemes to be registered to handle service worker.
|
|
|
std::string g_custom_service_worker_schemes = "";
|
|
|
|
|
|
-void Noop(scoped_refptr<content::SiteInstance>) {
|
|
|
+bool IsSameWebSite(content::BrowserContext* browser_context,
|
|
|
+ const GURL& src_url,
|
|
|
+ const GURL& dest_url) {
|
|
|
+ return content::SiteInstance::IsSameWebSite(browser_context, src_url,
|
|
|
+ dest_url) ||
|
|
|
+ // `IsSameWebSite` doesn't seem to work for some URIs such as `file:`,
|
|
|
+ // handle these scenarios by comparing only the site as defined by
|
|
|
+ // `GetSiteForURL`.
|
|
|
+ content::SiteInstance::GetSiteForURL(browser_context, dest_url) ==
|
|
|
+ src_url;
|
|
|
}
|
|
|
|
|
|
} // namespace
|
|
@@ -125,12 +134,7 @@ bool AtomBrowserClient::ShouldCreateNewSiteInstance(
|
|
|
|
|
|
// Create new a SiteInstance if navigating to a different site.
|
|
|
auto src_url = current_instance->GetSiteURL();
|
|
|
- return
|
|
|
- !content::SiteInstance::IsSameWebSite(browser_context, src_url, url) &&
|
|
|
- // `IsSameWebSite` doesn't seem to work for some URIs such as `file:`,
|
|
|
- // handle these scenarios by comparing only the site as defined by
|
|
|
- // `GetSiteForURL`.
|
|
|
- content::SiteInstance::GetSiteForURL(browser_context, url) != src_url;
|
|
|
+ return !IsSameWebSite(browser_context, src_url, url);
|
|
|
}
|
|
|
|
|
|
void AtomBrowserClient::AddProcessPreferences(
|
|
@@ -218,20 +222,19 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
|
|
void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
|
|
content::RenderFrameHost* rfh,
|
|
|
content::BrowserContext* browser_context,
|
|
|
- content::SiteInstance* current_instance,
|
|
|
const GURL& url,
|
|
|
+ bool has_request_started,
|
|
|
+ content::SiteInstance* candidate_instance,
|
|
|
content::SiteInstance** new_instance) {
|
|
|
if (g_suppress_renderer_process_restart) {
|
|
|
g_suppress_renderer_process_restart = false;
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ content::SiteInstance* current_instance = rfh->GetSiteInstance();
|
|
|
if (!ShouldCreateNewSiteInstance(rfh, browser_context, current_instance, url))
|
|
|
return;
|
|
|
|
|
|
- bool is_new_instance = true;
|
|
|
- scoped_refptr<content::SiteInstance> site_instance;
|
|
|
-
|
|
|
// Do we have an affinity site to manage ?
|
|
|
std::string affinity;
|
|
|
auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
|
|
@@ -241,35 +244,35 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
|
|
!affinity.empty()) {
|
|
|
affinity = base::ToLowerASCII(affinity);
|
|
|
auto iter = site_per_affinities.find(affinity);
|
|
|
- if (iter != site_per_affinities.end()) {
|
|
|
- site_instance = iter->second;
|
|
|
- is_new_instance = false;
|
|
|
+ GURL dest_site = content::SiteInstance::GetSiteForURL(browser_context, url);
|
|
|
+ if (iter != site_per_affinities.end() &&
|
|
|
+ IsSameWebSite(browser_context, iter->second->GetSiteURL(), dest_site)) {
|
|
|
+ *new_instance = iter->second;
|
|
|
} else {
|
|
|
- // We must not provide the url.
|
|
|
- // This site is "isolated" and must not be taken into account
|
|
|
- // when Chromium looking at a candidate for an url.
|
|
|
- site_instance = content::SiteInstance::Create(
|
|
|
- browser_context);
|
|
|
- site_per_affinities[affinity] = site_instance.get();
|
|
|
+ site_per_affinities[affinity] = candidate_instance;
|
|
|
+ *new_instance = candidate_instance;
|
|
|
+ // Remember the original web contents for the pending renderer process.
|
|
|
+ auto pending_process = candidate_instance->GetProcess();
|
|
|
+ pending_processes_[pending_process->GetID()] = web_contents;
|
|
|
}
|
|
|
} else {
|
|
|
- site_instance = content::SiteInstance::CreateForURL(
|
|
|
- browser_context,
|
|
|
- url);
|
|
|
- }
|
|
|
- *new_instance = site_instance.get();
|
|
|
-
|
|
|
- if (is_new_instance) {
|
|
|
- // Make sure the |site_instance| is not freed
|
|
|
- // when this function returns.
|
|
|
- // FIXME(zcbenz): We should adjust
|
|
|
- // OverrideSiteInstanceForNavigation's interface to solve this.
|
|
|
- BrowserThread::PostTask(
|
|
|
- BrowserThread::UI, FROM_HERE,
|
|
|
- base::Bind(&Noop, base::RetainedRef(site_instance)));
|
|
|
+ // OverrideSiteInstanceForNavigation will be called more than once during a
|
|
|
+ // navigation (currently twice, on request and when it's about to commit in
|
|
|
+ // the renderer), look at RenderFrameHostManager::GetFrameHostForNavigation.
|
|
|
+ // In the default mode we should resuse the same site instance until the
|
|
|
+ // request commits otherwise it will get destroyed. Currently there is no
|
|
|
+ // unique lifetime tracker for a navigation request during site instance
|
|
|
+ // creation. We check for the state of the request, which should be one of
|
|
|
+ // (WAITING_FOR_RENDERER_RESPONSE, STARTED, RESPONSE_STARTED, FAILED) along
|
|
|
+ // with the availability of a speculative render frame host.
|
|
|
+ if (has_request_started) {
|
|
|
+ *new_instance = current_instance;
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
+ *new_instance = candidate_instance;
|
|
|
// Remember the original web contents for the pending renderer process.
|
|
|
- auto pending_process = site_instance->GetProcess();
|
|
|
+ auto pending_process = candidate_instance->GetProcess();
|
|
|
pending_processes_[pending_process->GetID()] = web_contents;
|
|
|
}
|
|
|
}
|