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

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

Issue 799593004: Don't crash while detaching a pending child frame under --site-per-process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix compile after rebase Created 6 years 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/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 render_frame_delegate_(render_frame_delegate), 60 render_frame_delegate_(render_frame_delegate),
61 render_view_delegate_(render_view_delegate), 61 render_view_delegate_(render_view_delegate),
62 render_widget_delegate_(render_widget_delegate), 62 render_widget_delegate_(render_widget_delegate),
63 interstitial_page_(NULL), 63 interstitial_page_(NULL),
64 weak_factory_(this) { 64 weak_factory_(this) {
65 DCHECK(frame_tree_node_); 65 DCHECK(frame_tree_node_);
66 } 66 }
67 67
68 RenderFrameHostManager::~RenderFrameHostManager() { 68 RenderFrameHostManager::~RenderFrameHostManager() {
69 if (pending_render_frame_host_) 69 if (pending_render_frame_host_)
70 CancelPending(); 70 UnsetPendingRenderFrameHost();
71 71
72 // We should always have a current RenderFrameHost except in some tests. 72 // We should always have a current RenderFrameHost except in some tests.
73 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); 73 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>());
74 74
75 // Delete any swapped out RenderFrameHosts. 75 // Delete any swapped out RenderFrameHosts.
76 STLDeleteValues(&proxy_hosts_); 76 STLDeleteValues(&proxy_hosts_);
77 } 77 }
78 78
79 void RenderFrameHostManager::Init(BrowserContext* browser_context, 79 void RenderFrameHostManager::Init(BrowserContext* browser_context,
80 SiteInstance* site_instance, 80 SiteInstance* site_instance,
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 // We shouldn't get here for subframes, since we only swap subframes when 557 // We shouldn't get here for subframes, since we only swap subframes when
558 // --site-per-process is used. 558 // --site-per-process is used.
559 DCHECK(is_main_frame); 559 DCHECK(is_main_frame);
560 560
561 // The old RenderFrameHost will stay alive inside the proxy so that existing 561 // The old RenderFrameHost will stay alive inside the proxy so that existing
562 // JavaScript window references to it stay valid. 562 // JavaScript window references to it stay valid.
563 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass()); 563 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass());
564 } 564 }
565 } 565 }
566 566
567 void RenderFrameHostManager::DiscardUnusedFrame(
nasko 2014/12/12 21:54:49 In a parallel CL (https://codereview.chromium.org/
ncarter (slow) 2014/12/12 22:33:24 Done. I inlined it in an attempt to control the pr
568 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
569 // TODO(carlosk): this code is very similar to what can be found in
570 // SwapOutOldFrame and we should see that these are unified at some point.
571
572 // If the SiteInstance for the pending RFH is being used by others don't
573 // delete the RFH. Just swap it out and it can be reused at a later point.
574 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
575 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) {
576 // Any currently suspended navigations are no longer needed.
577 render_frame_host->CancelSuspendedNavigations();
578
579 RenderFrameProxyHost* proxy =
580 new RenderFrameProxyHost(site_instance, frame_tree_node_);
581 proxy_hosts_[site_instance->GetId()] = proxy;
582 render_frame_host->SwapOut(proxy);
583 if (frame_tree_node_->IsMainFrame())
584 proxy->TakeFrameHostOwnership(render_frame_host.Pass());
585 } else {
586 // We won't be coming back, so delete this one.
587 render_frame_host.reset();
588 }
589 }
590
591 void RenderFrameHostManager::MoveToPendingDeleteHosts( 567 void RenderFrameHostManager::MoveToPendingDeleteHosts(
592 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 568 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
593 // |render_frame_host| will be deleted when its SwapOut ACK is received, or 569 // |render_frame_host| will be deleted when its SwapOut ACK is received, or
594 // when the timer times out, or when the RFHM itself is deleted (whichever 570 // when the timer times out, or when the RFHM itself is deleted (whichever
595 // comes first). 571 // comes first).
596 pending_delete_hosts_.push_back( 572 pending_delete_hosts_.push_back(
597 linked_ptr<RenderFrameHostImpl>(render_frame_host.release())); 573 linked_ptr<RenderFrameHostImpl>(render_frame_host.release()));
598 } 574 }
599 575
600 bool RenderFrameHostManager::IsPendingDeletion( 576 bool RenderFrameHostManager::IsPendingDeletion(
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 new ViewMsg_EnableViewSourceMode( 1560 new ViewMsg_EnableViewSourceMode(
1585 render_frame_host_->render_view_host()->GetRoutingID())); 1561 render_frame_host_->render_view_host()->GetRoutingID()));
1586 } 1562 }
1587 1563
1588 return render_frame_host_.get(); 1564 return render_frame_host_.get();
1589 } 1565 }
1590 1566
1591 void RenderFrameHostManager::CancelPending() { 1567 void RenderFrameHostManager::CancelPending() {
1592 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", 1568 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending",
1593 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 1569 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
1570
1571 scoped_ptr<RenderFrameHostImpl> render_frame_host =
1572 UnsetPendingRenderFrameHost();
1573
1574 // TODO(carlosk): this code is very similar to what can be found in
1575 // SwapOutOldFrame and we should see that these are unified at some point.
1576
1577 // If the SiteInstance for the pending RFH is being used by others don't
1578 // delete the RFH. Just swap it out and it can be reused at a later point.
1579 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
1580 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) {
1581 // Any currently suspended navigations are no longer needed.
1582 render_frame_host->CancelSuspendedNavigations();
1583
1584 RenderFrameProxyHost* proxy =
1585 new RenderFrameProxyHost(site_instance, frame_tree_node_);
1586 proxy_hosts_[site_instance->GetId()] = proxy;
1587 render_frame_host->SwapOut(proxy);
1588 if (frame_tree_node_->IsMainFrame())
1589 proxy->TakeFrameHostOwnership(render_frame_host.Pass());
1590 } else {
1591 // We won't be coming back, so delete this one.
1592 render_frame_host.reset();
1593 }
1594 }
1595
1596 scoped_ptr<RenderFrameHostImpl>
1597 RenderFrameHostManager::UnsetPendingRenderFrameHost() {
1594 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = 1598 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host =
1595 pending_render_frame_host_.Pass(); 1599 pending_render_frame_host_.Pass();
1596 1600
1597 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( 1601 RenderViewDevToolsAgentHost::OnCancelPendingNavigation(
1598 pending_render_frame_host->render_view_host(), 1602 pending_render_frame_host->render_view_host(),
1599 render_frame_host_->render_view_host()); 1603 render_frame_host_->render_view_host());
1600 1604
1601 // We no longer need to prevent the process from exiting. 1605 // We no longer need to prevent the process from exiting.
1602 pending_render_frame_host->GetProcess()->RemovePendingView(); 1606 pending_render_frame_host->GetProcess()->RemovePendingView();
1603 1607
1604 DiscardUnusedFrame(pending_render_frame_host.Pass());
1605
1606 pending_web_ui_.reset(); 1608 pending_web_ui_.reset();
1607 pending_and_current_web_ui_.reset(); 1609 pending_and_current_web_ui_.reset();
1610
1611 return pending_render_frame_host.Pass();
1608 } 1612 }
1609 1613
1610 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( 1614 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
1611 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 1615 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
1612 // Swap the two. 1616 // Swap the two.
1613 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1617 scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
1614 render_frame_host_.Pass(); 1618 render_frame_host_.Pass();
1615 render_frame_host_ = render_frame_host.Pass(); 1619 render_frame_host_ = render_frame_host.Pass();
1616 1620
1617 if (frame_tree_node_->IsMainFrame()) { 1621 if (frame_tree_node_->IsMainFrame()) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 void RenderFrameHostManager::DeleteRenderFrameProxyHost( 1683 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
1680 SiteInstance* instance) { 1684 SiteInstance* instance) {
1681 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 1685 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
1682 if (iter != proxy_hosts_.end()) { 1686 if (iter != proxy_hosts_.end()) {
1683 delete iter->second; 1687 delete iter->second;
1684 proxy_hosts_.erase(iter); 1688 proxy_hosts_.erase(iter);
1685 } 1689 }
1686 } 1690 }
1687 1691
1688 } // namespace content 1692 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698