Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 697 proxy = CreateRenderFrameProxyHost(site_instance, | 697 proxy = CreateRenderFrameProxyHost(site_instance, |
| 698 render_frame_host->render_view_host()); | 698 render_frame_host->render_view_host()); |
| 699 } | 699 } |
| 700 } | 700 } |
| 701 | 701 |
| 702 render_frame_host.reset(); | 702 render_frame_host.reset(); |
| 703 } | 703 } |
| 704 | 704 |
| 705 void RenderFrameHostManager::MoveToPendingDeleteHosts( | 705 void RenderFrameHostManager::MoveToPendingDeleteHosts( |
| 706 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 706 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
| 707 // If this is the main frame going away and there are no more references to | |
| 708 // its RenderViewHost, mark it for deletion as well so that we don't try to | |
| 709 // reuse it. | |
| 710 if (render_frame_host->frame_tree_node()->IsMainFrame() && | |
| 711 render_frame_host->render_view_host()->ref_count() <= 1) { | |
| 712 render_frame_host->render_view_host()->set_pending_deletion(); | |
| 713 } | |
| 714 | |
| 715 // |render_frame_host| will be deleted when its SwapOut ACK is received, or | 707 // |render_frame_host| will be deleted when its SwapOut ACK is received, or |
| 716 // when the timer times out, or when the RFHM itself is deleted (whichever | 708 // when the timer times out, or when the RFHM itself is deleted (whichever |
| 717 // comes first). | 709 // comes first). |
| 718 pending_delete_hosts_.push_back(std::move(render_frame_host)); | 710 pending_delete_hosts_.push_back(std::move(render_frame_host)); |
| 719 } | 711 } |
| 720 | 712 |
| 721 bool RenderFrameHostManager::IsPendingDeletion( | 713 bool RenderFrameHostManager::IsPendingDeletion( |
| 722 RenderFrameHostImpl* render_frame_host) { | 714 RenderFrameHostImpl* render_frame_host) { |
| 723 for (const auto& rfh : pending_delete_hosts_) { | 715 for (const auto& rfh : pending_delete_hosts_) { |
| 724 if (rfh.get() == render_frame_host) | 716 if (rfh.get() == render_frame_host) |
| 725 return true; | 717 return true; |
| 726 } | 718 } |
| 727 return false; | 719 return false; |
| 728 } | 720 } |
| 729 | 721 |
| 722 bool RenderFrameHostManager::IsViewPendingDeletion( | |
| 723 RenderViewHostImpl* render_view_host) { | |
| 724 // Only safe to call this on the main frame. | |
| 725 CHECK(frame_tree_node_->IsMainFrame()); | |
| 726 | |
| 727 // The view is not pending deletion if more than one frame or proxy references | |
| 728 // it. | |
| 729 if (render_view_host->ref_count() > 1) | |
| 730 return false; | |
| 731 | |
| 732 // If the only thing referencing it is a frame on the pending deletion list, | |
| 733 // then this view will go away when the frame goes away. | |
| 734 for (const auto& rfh : pending_delete_hosts_) { | |
| 735 if (rfh->GetRenderViewHost() == render_view_host) | |
| 736 return true; | |
| 737 } | |
| 738 return false; | |
| 739 } | |
| 740 | |
| 730 bool RenderFrameHostManager::DeleteFromPendingList( | 741 bool RenderFrameHostManager::DeleteFromPendingList( |
| 731 RenderFrameHostImpl* render_frame_host) { | 742 RenderFrameHostImpl* render_frame_host) { |
| 732 for (RFHPendingDeleteList::iterator iter = pending_delete_hosts_.begin(); | 743 for (RFHPendingDeleteList::iterator iter = pending_delete_hosts_.begin(); |
| 733 iter != pending_delete_hosts_.end(); | 744 iter != pending_delete_hosts_.end(); |
| 734 iter++) { | 745 iter++) { |
| 735 if (iter->get() == render_frame_host) { | 746 if (iter->get() == render_frame_host) { |
| 736 pending_delete_hosts_.erase(iter); | 747 pending_delete_hosts_.erase(iter); |
| 737 return true; | 748 return true; |
| 738 } | 749 } |
| 739 } | 750 } |
| (...skipping 1663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2403 // we should still create a proxy, which will allow communicating with the | 2414 // we should still create a proxy, which will allow communicating with the |
| 2404 // opener until the pending RenderView commits, or if the pending navigation | 2415 // opener until the pending RenderView commits, or if the pending navigation |
| 2405 // is canceled. | 2416 // is canceled. |
| 2406 // PlzNavigate: similarly, if a speculative RenderViewHost is present, a | 2417 // PlzNavigate: similarly, if a speculative RenderViewHost is present, a |
| 2407 // proxy should be created. | 2418 // proxy should be created. |
| 2408 RenderViewHostImpl* rvh = frame_tree->GetRenderViewHost(instance); | 2419 RenderViewHostImpl* rvh = frame_tree->GetRenderViewHost(instance); |
| 2409 bool need_proxy_for_pending_rvh = (rvh == pending_render_view_host()); | 2420 bool need_proxy_for_pending_rvh = (rvh == pending_render_view_host()); |
| 2410 bool need_proxy_for_speculative_rvh = | 2421 bool need_proxy_for_speculative_rvh = |
| 2411 IsBrowserSideNavigationEnabled() && speculative_render_frame_host_ && | 2422 IsBrowserSideNavigationEnabled() && speculative_render_frame_host_ && |
| 2412 speculative_render_frame_host_->GetRenderViewHost() == rvh; | 2423 speculative_render_frame_host_->GetRenderViewHost() == rvh; |
| 2413 if (rvh && rvh->IsRenderViewLive() && !need_proxy_for_pending_rvh && | 2424 if (rvh && rvh->IsRenderViewLive() && !IsViewPendingDeletion(rvh) && |
|
alexmos
2016/03/29 18:43:01
Why is IsViewPendingDeletion necessary here? it s
Charlie Reis
2016/03/29 20:29:02
Ha! Good point. I put it in to make the test fai
| |
| 2414 !need_proxy_for_speculative_rvh) { | 2425 !need_proxy_for_pending_rvh && !need_proxy_for_speculative_rvh) { |
| 2415 return; | 2426 return; |
| 2416 } | 2427 } |
| 2417 | 2428 |
| 2418 if (rvh && !rvh->IsRenderViewLive()) { | 2429 if (rvh && !rvh->IsRenderViewLive()) { |
| 2419 EnsureRenderViewInitialized(rvh, instance); | 2430 EnsureRenderViewInitialized(rvh, instance); |
| 2420 } else { | 2431 } else { |
| 2421 // Create a RenderFrameProxyHost in the given SiteInstance if none | 2432 // Create a RenderFrameProxyHost in the given SiteInstance if none |
| 2422 // exists. Since an opener can point to a subframe, do this on the root | 2433 // exists. Since an opener can point to a subframe, do this on the root |
| 2423 // frame of the current opener's frame tree. | 2434 // frame of the current opener's frame tree. |
| 2424 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); | 2435 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2461 } else if (pending_render_frame_host_) { | 2472 } else if (pending_render_frame_host_) { |
| 2462 send_msg(pending_render_frame_host_.get(), | 2473 send_msg(pending_render_frame_host_.get(), |
| 2463 pending_render_frame_host_->GetRoutingID(), msg); | 2474 pending_render_frame_host_->GetRoutingID(), msg); |
| 2464 } | 2475 } |
| 2465 | 2476 |
| 2466 msg->set_routing_id(render_frame_host_->GetRoutingID()); | 2477 msg->set_routing_id(render_frame_host_->GetRoutingID()); |
| 2467 render_frame_host_->Send(msg); | 2478 render_frame_host_->Send(msg); |
| 2468 } | 2479 } |
| 2469 | 2480 |
| 2470 } // namespace content | 2481 } // namespace content |
| OLD | NEW |