Index: content/browser/frame_host/render_frame_host_manager.cc |
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc |
index 8b7448d1a331a76c68cb46c96470c84676f71246..8038ea304a849c8ab06a45cb2e4d2ff861e9f280 100644 |
--- a/content/browser/frame_host/render_frame_host_manager.cc |
+++ b/content/browser/frame_host/render_frame_host_manager.cc |
@@ -225,7 +225,7 @@ bool RenderFrameHostManager::ShouldCloseTabOnUnresponsiveRenderer() { |
// renderer will then be swapped in as part of the usual DidNavigate logic. |
// (If the unload handler later finishes, this call will be ignored because |
// the pending_nav_params_ state will already be cleaned up.) |
- current_host()->OnSwappedOut(true); |
+ current_host()->OnSwappedOut(true, false); |
} else if (render_view_host_->is_waiting_for_beforeunload_ack()) { |
// Haven't gotten around to starting the request, because we're still |
// waiting for the beforeunload handler to finish. We'll pretend that it |
@@ -244,8 +244,19 @@ void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) { |
// Make sure this is from our current RVH, and that we have a pending |
// navigation from OnCrossSiteResponse. (There may be no pending navigation |
// for data URLs that don't make network requests, for example.) If not, |
- // just return early and ignore. |
+ // it may be coming from an earlier RVH that was left to wait for the |
+ // execution of the unload event in the background. |
if (render_view_host != render_view_host_ || !pending_nav_params_.get()) { |
+ RenderViewHostImpl* render_view_host_impl = |
+ static_cast<RenderViewHostImpl*>(render_view_host); |
+ if (!static_cast<SiteInstanceImpl*>( |
+ render_view_host_impl->GetSiteInstance())->active_view_count() && |
+ !render_view_host_impl->should_be_preserved_on_swap_out()) { |
+ ShutdownRenderViewHostsInSiteInstance( |
+ render_view_host_impl->GetSiteInstance()->GetId()); |
+ // This is deleted while cleaning up the SiteInstance's views. |
+ render_view_host_impl = NULL; |
+ } |
pending_nav_params_.reset(); |
return; |
} |
@@ -276,10 +287,7 @@ void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) { |
pending_nav_params_->should_replace_current_entry, |
true); |
} else if (pending_render_view_host_) { |
- RenderProcessHostImpl* pending_process = |
- static_cast<RenderProcessHostImpl*>( |
- pending_render_view_host_->GetProcess()); |
- pending_process->ResumeDeferredNavigation( |
+ pending_render_view_host_->GetProcess()->ResumeDeferredNavigation( |
pending_nav_params_->global_request_id); |
} |
pending_nav_params_.reset(); |
@@ -881,13 +889,15 @@ void RenderFrameHostManager::CommitPending() { |
// this RVH was the last active one in the SiteInstance. Now that we |
// know that all RVHs are swapped out, we can delete all the RVHs in |
// this SiteInstance. |
- if (!static_cast<SiteInstanceImpl*>(old_render_view_host->GetSiteInstance())-> |
- active_view_count()) { |
+ if (!static_cast<SiteInstanceImpl*>(old_render_view_host->GetSiteInstance()) |
+ ->active_view_count() && |
Charlie Reis
2013/12/09 20:12:29
nit: Please keep the arrow at the end of the line,
|
+ !old_render_view_host->should_be_preserved_on_swap_out()) { |
Charlie Reis
2013/12/09 20:12:29
I'd like to avoid adding this here if possible.
|
ShutdownRenderViewHostsInSiteInstance( |
old_render_view_host->GetSiteInstance()->GetId()); |
- // This is deleted while cleaning up the SitaInstance's views. |
+ // This is deleted while cleaning up the SiteInstance's views. |
old_render_view_host = NULL; |
- } else if (old_render_view_host->IsRenderViewLive()) { |
+ } else if (old_render_view_host->IsRenderViewLive() || |
+ old_render_view_host->should_be_preserved_on_swap_out()) { |
// If the old RVH is live, we are swapping it out and should keep track of |
// it in case we navigate back to it. |
DCHECK(old_render_view_host->is_swapped_out()); |
@@ -924,8 +934,14 @@ void RenderFrameHostManager::ShutdownRenderViewHostsInSiteInstance( |
continue; |
RenderViewHostImpl* rvh = |
static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget)); |
- if (site_instance_id == rvh->GetSiteInstance()->GetId()) |
+ if (site_instance_id == rvh->GetSiteInstance()->GetId()) { |
+ // If the RVH was waiting for the unload event to execute in the |
+ // background, it may not have completely cleaned up its state yet. |
+ if (rvh->need_to_perform_clean_up_on_swapped_out()) { |
+ rvh->WasSwappedOut(); |
+ } |
rvh->Shutdown(); |
+ } |
} |
} |