Index: content/browser/frame_host/frame_tree.cc |
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc |
index f26c46c02360a0eda43722ffe1a1d417709e857a..c135da80d340fb2c3a90bdb3c57d138cc2fbfd91 100644 |
--- a/content/browser/frame_host/frame_tree.cc |
+++ b/content/browser/frame_host/frame_tree.cc |
@@ -178,7 +178,17 @@ RenderViewHostImpl* FrameTree::CreateRenderViewHostForMainFrame( |
DCHECK(main_frame_routing_id != MSG_ROUTING_NONE); |
RenderViewHostMap::iterator iter = |
render_view_host_map_.find(site_instance->GetId()); |
- CHECK(iter == render_view_host_map_.end()); |
+ if (iter != render_view_host_map_.end()) { |
+ // If a RenderViewHost is pending shutdown for this |site_instance|, put it |
+ // in the map of RenderViewHosts pending shutdown. Otherwise there should |
+ // not be a RenderViewHost for the SiteInstance. |
+ CHECK_EQ(RenderViewHostImpl::STATE_PENDING_SHUTDOWN, |
+ iter->second->rvh_state()); |
+ render_view_host_pending_shutdown_map_.insert( |
+ std::pair<int, RenderViewHostImpl*>(site_instance->GetId(), |
+ iter->second)); |
+ render_view_host_map_.erase(iter); |
+ } |
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( |
RenderViewHostFactory::Create(site_instance, |
render_view_delegate_, |
@@ -188,8 +198,7 @@ RenderViewHostImpl* FrameTree::CreateRenderViewHostForMainFrame( |
swapped_out, |
hidden)); |
- render_view_host_map_[site_instance->GetId()] = |
- RenderViewHostRefCount(rvh, 0); |
+ render_view_host_map_[site_instance->GetId()] = rvh; |
return rvh; |
} |
@@ -200,8 +209,7 @@ RenderViewHostImpl* FrameTree::GetRenderViewHostForSubFrame( |
// TODO(creis): Mirror the frame tree so this check can't fail. |
if (iter == render_view_host_map_.end()) |
return NULL; |
- RenderViewHostRefCount rvh_refcount = iter->second; |
- return rvh_refcount.first; |
+ return iter->second; |
} |
void FrameTree::RegisterRenderFrameHost( |
@@ -212,26 +220,51 @@ void FrameTree::RegisterRenderFrameHost( |
render_view_host_map_.find(site_instance->GetId()); |
CHECK(iter != render_view_host_map_.end()); |
- // Increment the refcount. |
- CHECK_GE(iter->second.second, 0); |
- iter->second.second++; |
+ iter->second->increment_ref_count(); |
} |
void FrameTree::UnregisterRenderFrameHost( |
RenderFrameHostImpl* render_frame_host) { |
SiteInstance* site_instance = |
render_frame_host->render_view_host()->GetSiteInstance(); |
+ int32 site_instance_id = site_instance->GetId(); |
RenderViewHostMap::iterator iter = |
- render_view_host_map_.find(site_instance->GetId()); |
- CHECK(iter != render_view_host_map_.end()); |
- |
- // Decrement the refcount and shutdown the RenderViewHost if no one else is |
- // using it. |
- CHECK_GT(iter->second.second, 0); |
- iter->second.second--; |
- if (iter->second.second == 0) { |
- iter->second.first->Shutdown(); |
- render_view_host_map_.erase(iter); |
+ render_view_host_map_.find(site_instance_id); |
+ if (iter != render_view_host_map_.end() && |
+ iter->second == render_frame_host->render_view_host()) { |
+ // Decrement the refcount and shutdown the RenderViewHost if no one else is |
+ // using it. |
+ CHECK_GT(iter->second->ref_count(), 0); |
+ iter->second->decrement_ref_count(); |
+ if (iter->second->ref_count() == 0) { |
+ iter->second->Shutdown(); |
+ render_view_host_map_.erase(iter); |
+ } |
+ } else { |
+ // The RenderViewHost should be in the list of RenderViewHosts pending |
+ // shutdown. |
+ bool render_view_host_found = false; |
+ std::pair<RenderViewHostMultiMap::iterator, |
+ RenderViewHostMultiMap::iterator> result = |
+ render_view_host_pending_shutdown_map_.equal_range(site_instance_id); |
+ for (RenderViewHostMultiMap::iterator multi_iter = result.first; |
+ multi_iter != result.second; |
+ ++multi_iter) { |
+ if (multi_iter->second != render_frame_host->render_view_host()) |
+ continue; |
+ render_view_host_found = true; |
+ RenderViewHostImpl* rvh = multi_iter->second; |
+ // Decrement the refcount and shutdown the RenderViewHost if no one else |
+ // is using it. |
+ CHECK_GT(rvh->ref_count(), 0); |
+ rvh->decrement_ref_count(); |
+ if (rvh->ref_count() == 0) { |
+ rvh->Shutdown(); |
+ render_view_host_pending_shutdown_map_.erase(multi_iter); |
+ } |
+ break; |
+ } |
+ CHECK(render_view_host_found); |
} |
} |