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

Side by Side Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 1055203002: Fix the RenderFrameProxyHost mop-up logic in RenderFrameHostManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: EXPECT_ instead of ASSERT_ Created 5 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/frame_host/render_frame_host_manager.h" 5 #include "content/browser/frame_host/render_frame_host_manager.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 render_frame_delegate_(render_frame_delegate), 61 render_frame_delegate_(render_frame_delegate),
62 render_view_delegate_(render_view_delegate), 62 render_view_delegate_(render_view_delegate),
63 render_widget_delegate_(render_widget_delegate), 63 render_widget_delegate_(render_widget_delegate),
64 interstitial_page_(nullptr), 64 interstitial_page_(nullptr),
65 should_reuse_web_ui_(false), 65 should_reuse_web_ui_(false),
66 weak_factory_(this) { 66 weak_factory_(this) {
67 DCHECK(frame_tree_node_); 67 DCHECK(frame_tree_node_);
68 } 68 }
69 69
70 RenderFrameHostManager::~RenderFrameHostManager() { 70 RenderFrameHostManager::~RenderFrameHostManager() {
71 if (pending_render_frame_host_) 71 if (pending_render_frame_host_) {
72 UnsetPendingRenderFrameHost(); 72 scoped_ptr<RenderFrameHostImpl> relic = UnsetPendingRenderFrameHost();
73 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get());
74 }
73 75
74 if (speculative_render_frame_host_) 76 if (speculative_render_frame_host_) {
75 UnsetSpeculativeRenderFrameHost(); 77 scoped_ptr<RenderFrameHostImpl> relic = UnsetSpeculativeRenderFrameHost();
78 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get());
79 }
76 80
77 if (render_frame_host_ && 81 ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host_.get());
78 render_frame_host_->GetSiteInstance()->active_frame_count() <= 1U) {
79 ShutdownRenderFrameProxyHostsInSiteInstance(
80 render_frame_host_->GetSiteInstance()->GetId());
81 }
82 82
83 // Delete any RenderFrameProxyHosts and swapped out RenderFrameHosts. 83 // Delete any RenderFrameProxyHosts and swapped out RenderFrameHosts.
84 // It is important to delete those prior to deleting the current 84 // It is important to delete those prior to deleting the current
85 // RenderFrameHost, since the CrossProcessFrameConnector (owned by 85 // RenderFrameHost, since the CrossProcessFrameConnector (owned by
86 // RenderFrameProxyHost) points to the RenderWidgetHostView associated with 86 // RenderFrameProxyHost) points to the RenderWidgetHostView associated with
87 // the current RenderFrameHost and uses it during its destructor. 87 // the current RenderFrameHost and uses it during its destructor.
88 STLDeleteValues(&proxy_hosts_); 88 STLDeleteValues(&proxy_hosts_);
89 89
90 // Release the WebUI prior to resetting the current RenderFrameHost, as the 90 // Release the WebUI prior to resetting the current RenderFrameHost, as the
91 // WebUI accesses the RenderFrameHost during cleanup. 91 // WebUI accesses the RenderFrameHost during cleanup.
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 // Now close any modal dialogs that would prevent us from swapping out. This 597 // Now close any modal dialogs that would prevent us from swapping out. This
598 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is 598 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is
599 // no longer on the stack when we send the SwapOut message. 599 // no longer on the stack when we send the SwapOut message.
600 delegate_->CancelModalDialogsForRenderManager(); 600 delegate_->CancelModalDialogsForRenderManager();
601 601
602 // If the old RFH is not live, just return as there is no further work to do. 602 // If the old RFH is not live, just return as there is no further work to do.
603 // It will be deleted and there will be no proxy created. 603 // It will be deleted and there will be no proxy created.
604 int32 old_site_instance_id = 604 int32 old_site_instance_id =
605 old_render_frame_host->GetSiteInstance()->GetId(); 605 old_render_frame_host->GetSiteInstance()->GetId();
606 if (!old_render_frame_host->IsRenderFrameLive()) { 606 if (!old_render_frame_host->IsRenderFrameLive()) {
607 ShutdownRenderFrameProxyHostsInSiteInstance(old_site_instance_id); 607 ShutdownProxiesIfLastActiveFrameInSiteInstance(old_render_frame_host.get());
608 return; 608 return;
609 } 609 }
610 610
611 // If there are no active frames besides this one, we can delete the old 611 // If there are no active frames besides this one, we can delete the old
612 // RenderFrameHost once it runs its unload handler, without replacing it with 612 // RenderFrameHost once it runs its unload handler, without replacing it with
613 // a proxy. 613 // a proxy.
614 size_t active_frame_count = 614 size_t active_frame_count =
615 old_render_frame_host->GetSiteInstance()->active_frame_count(); 615 old_render_frame_host->GetSiteInstance()->active_frame_count();
616 if (active_frame_count <= 1) { 616 if (active_frame_count <= 1) {
617 // Tell the old RenderFrameHost to swap out, with no proxy to replace it. 617 // Tell the old RenderFrameHost to swap out, with no proxy to replace it.
618 old_render_frame_host->SwapOut(NULL, true); 618 old_render_frame_host->SwapOut(NULL, true);
619 MoveToPendingDeleteHosts(old_render_frame_host.Pass()); 619 MoveToPendingDeleteHosts(old_render_frame_host.Pass());
620 620
621 // Also clear out any proxies from this SiteInstance, in case this was the 621 // Also clear out any proxies from this SiteInstance, in case this was the
622 // last one keeping other proxies alive. 622 // last one keeping other proxies alive.
623 ShutdownRenderFrameProxyHostsInSiteInstance(old_site_instance_id); 623 ShutdownProxiesIfLastActiveFrameInSiteInstance(old_render_frame_host.get());
624
625 return; 624 return;
626 } 625 }
627 626
628 // Otherwise there are active views and we need a proxy for the old RFH. 627 // Otherwise there are active views and we need a proxy for the old RFH.
629 // (There should not be one yet.) 628 // (There should not be one yet.)
630 CHECK(!GetRenderFrameProxyHost(old_render_frame_host->GetSiteInstance())); 629 CHECK(!GetRenderFrameProxyHost(old_render_frame_host->GetSiteInstance()));
631 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( 630 RenderFrameProxyHost* proxy = new RenderFrameProxyHost(
632 old_render_frame_host->GetSiteInstance(), frame_tree_node_); 631 old_render_frame_host->GetSiteInstance(), frame_tree_node_);
633 CHECK(proxy_hosts_.insert(std::make_pair(old_site_instance_id, proxy)).second) 632 CHECK(proxy_hosts_.insert(std::make_pair(old_site_instance_id, proxy)).second)
634 << "Inserting a duplicate item."; 633 << "Inserting a duplicate item.";
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 675
677 // Check if the RenderFrameHost is already swapped out, to avoid swapping it 676 // Check if the RenderFrameHost is already swapped out, to avoid swapping it
678 // out again. 677 // out again.
679 if (!render_frame_host->is_swapped_out()) 678 if (!render_frame_host->is_swapped_out())
680 render_frame_host->SwapOut(proxy, false); 679 render_frame_host->SwapOut(proxy, false);
681 680
682 if (frame_tree_node_->IsMainFrame()) 681 if (frame_tree_node_->IsMainFrame())
683 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); 682 proxy->TakeFrameHostOwnership(render_frame_host.Pass());
684 } else { 683 } else {
685 // We won't be coming back, so delete this one. 684 // We won't be coming back, so delete this one.
685 ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host.get());
686 render_frame_host.reset(); 686 render_frame_host.reset();
687 } 687 }
688 } 688 }
689 689
690 void RenderFrameHostManager::MoveToPendingDeleteHosts( 690 void RenderFrameHostManager::MoveToPendingDeleteHosts(
691 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 691 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
692 // |render_frame_host| will be deleted when its SwapOut ACK is received, or 692 // |render_frame_host| will be deleted when its SwapOut ACK is received, or
693 // when the timer times out, or when the RFHM itself is deleted (whichever 693 // when the timer times out, or when the RFHM itself is deleted (whichever
694 // comes first). 694 // comes first).
695 pending_delete_hosts_.push_back( 695 pending_delete_hosts_.push_back(
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 if (proxy_to_parent) 1747 if (proxy_to_parent)
1748 proxy_to_parent->SetChildRWHView(render_frame_host_->GetView()); 1748 proxy_to_parent->SetChildRWHView(render_frame_host_->GetView());
1749 } 1749 }
1750 1750
1751 // After all is done, there must never be a proxy in the list which has the 1751 // After all is done, there must never be a proxy in the list which has the
1752 // same SiteInstance as the current RenderFrameHost. 1752 // same SiteInstance as the current RenderFrameHost.
1753 CHECK(proxy_hosts_.find(render_frame_host_->GetSiteInstance()->GetId()) == 1753 CHECK(proxy_hosts_.find(render_frame_host_->GetSiteInstance()->GetId()) ==
1754 proxy_hosts_.end()); 1754 proxy_hosts_.end());
1755 } 1755 }
1756 1756
1757 void RenderFrameHostManager::ShutdownRenderFrameProxyHostsInSiteInstance( 1757 void RenderFrameHostManager::ShutdownProxiesIfLastActiveFrameInSiteInstance(
1758 int32 site_instance_id) { 1758 RenderFrameHostImpl* render_frame_host) {
1759 // First remove any swapped out RFH for this SiteInstance from our own list. 1759 if (!render_frame_host)
1760 return;
1761 if (!RenderFrameHostImpl::IsRFHStateActive(render_frame_host->rfh_state()))
1762 return;
1763 if (render_frame_host->GetSiteInstance()->active_frame_count() > 1U)
1764 return;
1765
1766 // After |render_frame_host| goes away, there will be no active frames left in
1767 // its SiteInstance, so we can delete all proxies created in that SiteInstance
1768 // on behalf of frames anywhere in the BrowsingInstance.
1769 int32 site_instance_id = render_frame_host->GetSiteInstance()->GetId();
1770
1771 // First remove any proxies for this SiteInstance from our own list.
1760 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); 1772 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_);
1761 1773
1762 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts 1774 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts
1763 // in the SiteInstance, then tell their respective FrameTrees to remove all 1775 // in the SiteInstance, then tell their respective FrameTrees to remove all
1764 // RenderFrameProxyHosts corresponding to them. 1776 // RenderFrameProxyHosts corresponding to them.
1765 // TODO(creis): Replace this with a RenderFrameHostIterator that protects 1777 // TODO(creis): Replace this with a RenderFrameHostIterator that protects
1766 // against use-after-frees if a later element is deleted before getting to it. 1778 // against use-after-frees if a later element is deleted before getting to it.
1767 scoped_ptr<RenderWidgetHostIterator> widgets( 1779 scoped_ptr<RenderWidgetHostIterator> widgets(
1768 RenderWidgetHostImpl::GetAllRenderWidgetHosts()); 1780 RenderWidgetHostImpl::GetAllRenderWidgetHosts());
1769 while (RenderWidgetHost* widget = widgets->GetNextHost()) { 1781 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 void RenderFrameHostManager::DeleteRenderFrameProxyHost( 2031 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
2020 SiteInstance* instance) { 2032 SiteInstance* instance) {
2021 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 2033 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
2022 if (iter != proxy_hosts_.end()) { 2034 if (iter != proxy_hosts_.end()) {
2023 delete iter->second; 2035 delete iter->second;
2024 proxy_hosts_.erase(iter); 2036 proxy_hosts_.erase(iter);
2025 } 2037 }
2026 } 2038 }
2027 2039
2028 } // namespace content 2040 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698