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

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

Issue 281663002: Create RenderFrameProxyHost at time of swap-out instead of commit. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix IPC_BEGIN_MESSAGE_MAP macro, as _EX version doesn't exist anymore. Created 6 years, 7 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 | Annotate | Revision Log
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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 return NULL; // We weren't able to create a pending render frame host. 168 return NULL; // We weren't able to create a pending render frame host.
169 169
170 // If the current render_frame_host_ isn't live, we should create it so 170 // If the current render_frame_host_ isn't live, we should create it so
171 // that we don't show a sad tab while the dest_render_frame_host fetches 171 // that we don't show a sad tab while the dest_render_frame_host fetches
172 // its first page. (Bug 1145340) 172 // its first page. (Bug 1145340)
173 if (dest_render_frame_host != render_frame_host_ && 173 if (dest_render_frame_host != render_frame_host_ &&
174 !render_frame_host_->render_view_host()->IsRenderViewLive()) { 174 !render_frame_host_->render_view_host()->IsRenderViewLive()) {
175 // Note: we don't call InitRenderView here because we are navigating away 175 // Note: we don't call InitRenderView here because we are navigating away
176 // soon anyway, and we don't have the NavigationEntry for this host. 176 // soon anyway, and we don't have the NavigationEntry for this host.
177 delegate_->CreateRenderViewForRenderManager( 177 delegate_->CreateRenderViewForRenderManager(
178 render_frame_host_->render_view_host(), MSG_ROUTING_NONE, NULL); 178 render_frame_host_->render_view_host(), MSG_ROUTING_NONE,
179 MSG_ROUTING_NONE, NULL);
179 } 180 }
180 181
181 // If the renderer crashed, then try to create a new one to satisfy this 182 // If the renderer crashed, then try to create a new one to satisfy this
182 // navigation request. 183 // navigation request.
183 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) { 184 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) {
184 // Recreate the opener chain. 185 // Recreate the opener chain.
185 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( 186 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
186 dest_render_frame_host->GetSiteInstance()); 187 dest_render_frame_host->GetSiteInstance());
187 if (!InitRenderView(dest_render_frame_host->render_view_host(), 188 if (!InitRenderView(dest_render_frame_host->render_view_host(),
188 opener_route_id)) 189 opener_route_id, MSG_ROUTING_NONE))
189 return NULL; 190 return NULL;
190 191
191 // Now that we've created a new renderer, be sure to hide it if it isn't 192 // Now that we've created a new renderer, be sure to hide it if it isn't
192 // our primary one. Otherwise, we might crash if we try to call Show() 193 // our primary one. Otherwise, we might crash if we try to call Show()
193 // on it later. 194 // on it later.
194 if (dest_render_frame_host != render_frame_host_ && 195 if (dest_render_frame_host != render_frame_host_ &&
195 dest_render_frame_host->render_view_host()->GetView()) { 196 dest_render_frame_host->render_view_host()->GetView()) {
196 dest_render_frame_host->render_view_host()->GetView()->Hide(); 197 dest_render_frame_host->render_view_host()->GetView()->Hide();
197 } else if (frame_tree_node_->IsMainFrame()) { 198 } else if (frame_tree_node_->IsMainFrame()) {
198 // This is our primary renderer, notify here as we won't be calling 199 // This is our primary renderer, notify here as we won't be calling
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 } 445 }
445 446
446 // TODO(creis): Take in RenderFrameHost instead, since frames can have openers. 447 // TODO(creis): Take in RenderFrameHost instead, since frames can have openers.
447 void RenderFrameHostManager::DidDisownOpener(RenderViewHost* render_view_host) { 448 void RenderFrameHostManager::DidDisownOpener(RenderViewHost* render_view_host) {
448 // Notify all swapped out hosts, including the pending RVH. 449 // Notify all swapped out hosts, including the pending RVH.
449 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); 450 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
450 iter != proxy_hosts_.end(); 451 iter != proxy_hosts_.end();
451 ++iter) { 452 ++iter) {
452 DCHECK_NE(iter->second->GetSiteInstance(), 453 DCHECK_NE(iter->second->GetSiteInstance(),
453 current_frame_host()->GetSiteInstance()); 454 current_frame_host()->GetSiteInstance());
454 iter->second->render_view_host()->DisownOpener(); 455 iter->second->GetRenderViewHost()->DisownOpener();
455 } 456 }
456 } 457 }
457 458
458 void RenderFrameHostManager::RendererProcessClosing( 459 void RenderFrameHostManager::RendererProcessClosing(
459 RenderProcessHost* render_process_host) { 460 RenderProcessHost* render_process_host) {
460 // Remove any swapped out RVHs from this process, so that we don't try to 461 // Remove any swapped out RVHs from this process, so that we don't try to
461 // swap them back in while the process is exiting. Start by finding them, 462 // swap them back in while the process is exiting. Start by finding them,
462 // since there could be more than one. 463 // since there could be more than one.
463 std::list<int> ids_to_remove; 464 std::list<int> ids_to_remove;
464 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); 465 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 // The same CrossProcessFrameConnector is used for subsequent cross- 500 // The same CrossProcessFrameConnector is used for subsequent cross-
500 // process navigations, but it will be destroyed if the Frame is 501 // process navigations, but it will be destroyed if the Frame is
501 // navigated back to the same site instance as its parent. 502 // navigated back to the same site instance as its parent.
502 // TODO(kenrb): This will change when RenderFrameProxyHost is created. 503 // TODO(kenrb): This will change when RenderFrameProxyHost is created.
503 if (!cross_process_frame_connector_) { 504 if (!cross_process_frame_connector_) {
504 cross_process_frame_connector_ = 505 cross_process_frame_connector_ =
505 new CrossProcessFrameConnector(render_frame_host_.get()); 506 new CrossProcessFrameConnector(render_frame_host_.get());
506 } 507 }
507 } 508 }
508 509
510 // Create the RenderFrameProxyHost that will replace the
511 // RenderFrameHost which is swapping out. If one exists, ensure it is deleted
512 // from the map and not leaked.
513 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(
514 render_frame_host_->GetSiteInstance()->GetId());
515 if (iter != proxy_hosts_.end()) {
516 delete iter->second;
517 proxy_hosts_.erase(iter);
518 }
519
520 RenderFrameProxyHost* proxy = new RenderFrameProxyHost(
521 render_frame_host_->GetSiteInstance(), frame_tree_node_);
522 proxy_hosts_[render_frame_host_->GetSiteInstance()->GetId()] = proxy;
523
509 // Tell the old frame it is being swapped out. This will fire the unload 524 // Tell the old frame it is being swapped out. This will fire the unload
510 // handler in the background (without firing the beforeunload handler a second 525 // handler in the background (without firing the beforeunload handler a second
511 // time). When the navigation completes, we will send a message to the 526 // time). When the navigation completes, we will send a message to the
512 // ResourceDispatcherHost, allowing the pending RVH's response to resume. 527 // ResourceDispatcherHost, allowing the pending RVH's response to resume.
513 render_frame_host_->SwapOut(); 528 render_frame_host_->SwapOut(proxy);
514 529
515 // ResourceDispatcherHost has told us to run the onunload handler, which 530 // ResourceDispatcherHost has told us to run the onunload handler, which
516 // means it is not a download or unsafe page, and we are going to perform the 531 // means it is not a download or unsafe page, and we are going to perform the
517 // navigation. Thus, we no longer need to remember that the RenderFrameHost 532 // navigation. Thus, we no longer need to remember that the RenderFrameHost
518 // is part of a pending cross-site request. 533 // is part of a pending cross-site request.
519 if (pending_render_frame_host_) { 534 if (pending_render_frame_host_) {
520 pending_render_frame_host_->render_view_host()-> 535 pending_render_frame_host_->render_view_host()->
521 SetHasPendingCrossSiteRequest(false); 536 SetHasPendingCrossSiteRequest(false);
522 } 537 }
523 } 538 }
(...skipping 25 matching lines...) Expand all
549 564
550 bool RenderFrameHostManager::ClearProxiesInSiteInstance( 565 bool RenderFrameHostManager::ClearProxiesInSiteInstance(
551 int32 site_instance_id, 566 int32 site_instance_id,
552 FrameTreeNode* node) { 567 FrameTreeNode* node) {
553 RenderFrameProxyHostMap::iterator iter = 568 RenderFrameProxyHostMap::iterator iter =
554 node->render_manager()->proxy_hosts_.find(site_instance_id); 569 node->render_manager()->proxy_hosts_.find(site_instance_id);
555 if (iter != node->render_manager()->proxy_hosts_.end()) { 570 if (iter != node->render_manager()->proxy_hosts_.end()) {
556 RenderFrameProxyHost* proxy = iter->second; 571 RenderFrameProxyHost* proxy = iter->second;
557 // If the RVH is pending swap out, it needs to switch state to 572 // If the RVH is pending swap out, it needs to switch state to
558 // pending shutdown. Otherwise it is deleted. 573 // pending shutdown. Otherwise it is deleted.
559 if (proxy->render_view_host()->rvh_state() == 574 if (proxy->GetRenderViewHost()->rvh_state() ==
560 RenderViewHostImpl::STATE_PENDING_SWAP_OUT) { 575 RenderViewHostImpl::STATE_PENDING_SWAP_OUT) {
561 scoped_ptr<RenderFrameHostImpl> swapped_out_rfh = proxy->PassFrameHost(); 576 scoped_ptr<RenderFrameHostImpl> swapped_out_rfh =
577 proxy->PassFrameHostOwnership();
562 578
563 swapped_out_rfh->SetPendingShutdown(base::Bind( 579 swapped_out_rfh->SetPendingShutdown(base::Bind(
564 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, 580 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance,
565 node->render_manager()->weak_factory_.GetWeakPtr(), 581 node->render_manager()->weak_factory_.GetWeakPtr(),
566 site_instance_id, 582 site_instance_id,
567 swapped_out_rfh.get())); 583 swapped_out_rfh.get()));
568 RFHPendingDeleteMap::iterator pending_delete_iter = 584 RFHPendingDeleteMap::iterator pending_delete_iter =
569 node->render_manager()->pending_delete_hosts_.find(site_instance_id); 585 node->render_manager()->pending_delete_hosts_.find(site_instance_id);
570 if (pending_delete_iter == 586 if (pending_delete_iter ==
571 node->render_manager()->pending_delete_hosts_.end() || 587 node->render_manager()->pending_delete_hosts_.end() ||
572 pending_delete_iter->second.get() != swapped_out_rfh) { 588 pending_delete_iter->second.get() != swapped_out_rfh) {
573 node->render_manager()->pending_delete_hosts_[site_instance_id] = 589 node->render_manager()->pending_delete_hosts_[site_instance_id] =
574 linked_ptr<RenderFrameHostImpl>(swapped_out_rfh.release()); 590 linked_ptr<RenderFrameHostImpl>(swapped_out_rfh.release());
575 } 591 }
576 } else {
577 delete proxy;
578 } 592 }
593 delete proxy;
579 node->render_manager()->proxy_hosts_.erase(site_instance_id); 594 node->render_manager()->proxy_hosts_.erase(site_instance_id);
580 } 595 }
581 596
582 return true; 597 return true;
583 } 598 }
584 599
585 bool RenderFrameHostManager::ShouldTransitionCrossSite() { 600 bool RenderFrameHostManager::ShouldTransitionCrossSite() {
586 // False in the single-process mode, as it makes RVHs to accumulate 601 // False in the single-process mode, as it makes RVHs to accumulate
587 // in swapped_out_hosts_. 602 // in swapped_out_hosts_.
588 // True if we are using process-per-site-instance (default) or 603 // True if we are using process-per-site-instance (default) or
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); 905 CHECK_NE(render_frame_host_->GetSiteInstance(), instance);
891 906
892 // Check if we've already created an RFH for this SiteInstance. If so, try 907 // Check if we've already created an RFH for this SiteInstance. If so, try
893 // to re-use the existing one, which has already been initialized. We'll 908 // to re-use the existing one, which has already been initialized. We'll
894 // remove it from the list of swapped out hosts if it commits. 909 // remove it from the list of swapped out hosts if it commits.
895 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); 910 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
896 911
897 FrameTreeNode* parent_node = frame_tree_node_->parent(); 912 FrameTreeNode* parent_node = frame_tree_node_->parent();
898 913
899 if (proxy) { 914 if (proxy) {
900 routing_id = proxy->render_view_host()->GetRoutingID(); 915 routing_id = proxy->GetRenderViewHost()->GetRoutingID();
901 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. 916 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
902 // Prevent the process from exiting while we're trying to use it. 917 // Prevent the process from exiting while we're trying to use it.
903 if (!swapped_out) { 918 if (!swapped_out) {
904 new_render_frame_host = proxy->PassFrameHost(); 919 new_render_frame_host = proxy->PassFrameHostOwnership();
905 new_render_frame_host->GetProcess()->AddPendingView(); 920 new_render_frame_host->GetProcess()->AddPendingView();
906 921
907 proxy_hosts_.erase(instance->GetId()); 922 proxy_hosts_.erase(instance->GetId());
908 delete proxy; 923 delete proxy;
909 924
910 // When a new render view is created by the renderer, the new WebContents 925 // When a new render view is created by the renderer, the new WebContents
911 // gets a RenderViewHost in the SiteInstance of its opener WebContents. 926 // gets a RenderViewHost in the SiteInstance of its opener WebContents.
912 // If not used in the first navigation, this RVH is swapped out and is not 927 // If not used in the first navigation, this RVH is swapped out and is not
913 // granted bindings, so we may need to grant them when swapping it in. 928 // granted bindings, so we may need to grant them when swapping it in.
914 if (pending_web_ui() && !new_render_frame_host->GetProcess()->IsGuest()) { 929 if (pending_web_ui() && !new_render_frame_host->GetProcess()->IsGuest()) {
(...skipping 13 matching lines...) Expand all
928 delete cross_process_frame_connector_; 943 delete cross_process_frame_connector_;
929 cross_process_frame_connector_ = NULL; 944 cross_process_frame_connector_ = NULL;
930 } 945 }
931 } 946 }
932 } else { 947 } else {
933 // Create a new RenderFrameHost if we don't find an existing one. 948 // Create a new RenderFrameHost if we don't find an existing one.
934 new_render_frame_host = CreateRenderFrameHost( 949 new_render_frame_host = CreateRenderFrameHost(
935 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); 950 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden);
936 RenderViewHostImpl* render_view_host = 951 RenderViewHostImpl* render_view_host =
937 new_render_frame_host->render_view_host(); 952 new_render_frame_host->render_view_host();
953 int proxy_routing_id = MSG_ROUTING_NONE;
938 954
939 // Prevent the process from exiting while we're trying to navigate in it. 955 // Prevent the process from exiting while we're trying to navigate in it.
940 // Otherwise, if the new RFH is swapped out already, store it. 956 // Otherwise, if the new RFH is swapped out already, store it.
941 if (!swapped_out) { 957 if (!swapped_out) {
942 new_render_frame_host->GetProcess()->AddPendingView(); 958 new_render_frame_host->GetProcess()->AddPendingView();
943 } else { 959 } else {
944 proxy_hosts_[instance->GetId()] = new RenderFrameProxyHost( 960 proxy = new RenderFrameProxyHost(
945 new_render_frame_host.Pass()); 961 new_render_frame_host->GetSiteInstance(), frame_tree_node_);
962 proxy_hosts_[instance->GetId()] = proxy;
963 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass());
964 proxy_routing_id = proxy->GetRoutingID();
946 } 965 }
947 966
948 bool success = InitRenderView(render_view_host, opener_route_id); 967 bool success = InitRenderView(
968 render_view_host, opener_route_id, proxy_routing_id);
949 if (success && frame_tree_node_->IsMainFrame()) { 969 if (success && frame_tree_node_->IsMainFrame()) {
950 // Don't show the main frame's view until we get a DidNavigate from it. 970 // Don't show the main frame's view until we get a DidNavigate from it.
951 render_view_host->GetView()->Hide(); 971 render_view_host->GetView()->Hide();
952 } else if (!swapped_out && pending_render_frame_host_) { 972 } else if (!swapped_out && pending_render_frame_host_) {
953 CancelPending(); 973 CancelPending();
954 } 974 }
955 routing_id = render_view_host->GetRoutingID(); 975 routing_id = render_view_host->GetRoutingID();
956 } 976 }
957 977
958 // Use this as our new pending RFH if it isn't swapped out. 978 // Use this as our new pending RFH if it isn't swapped out.
959 if (!swapped_out) 979 if (!swapped_out)
960 pending_render_frame_host_ = new_render_frame_host.Pass(); 980 pending_render_frame_host_ = new_render_frame_host.Pass();
961 981
962 return routing_id; 982 return routing_id;
963 } 983 }
964 984
965 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host, 985 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host,
966 int opener_route_id) { 986 int opener_route_id,
987 int proxy_routing_id) {
967 // We may have initialized this RenderViewHost for another RenderFrameHost. 988 // We may have initialized this RenderViewHost for another RenderFrameHost.
968 if (render_view_host->IsRenderViewLive()) 989 if (render_view_host->IsRenderViewLive())
969 return true; 990 return true;
970 991
971 // If the pending navigation is to a WebUI and the RenderView is not in a 992 // If the pending navigation is to a WebUI and the RenderView is not in a
972 // guest process, tell the RenderViewHost about any bindings it will need 993 // guest process, tell the RenderViewHost about any bindings it will need
973 // enabled. 994 // enabled.
974 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) { 995 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) {
975 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 996 render_view_host->AllowBindings(pending_web_ui()->GetBindings());
976 } else { 997 } else {
977 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled 998 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
978 // process unless it's swapped out. 999 // process unless it's swapped out.
979 RenderViewHostImpl* rvh_impl = 1000 RenderViewHostImpl* rvh_impl =
980 static_cast<RenderViewHostImpl*>(render_view_host); 1001 static_cast<RenderViewHostImpl*>(render_view_host);
981 if (!rvh_impl->IsSwappedOut()) { 1002 if (!rvh_impl->IsSwappedOut()) {
982 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 1003 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
983 render_view_host->GetProcess()->GetID())); 1004 render_view_host->GetProcess()->GetID()));
984 } 1005 }
985 } 1006 }
986 1007
987 return delegate_->CreateRenderViewForRenderManager( 1008 return delegate_->CreateRenderViewForRenderManager(
988 render_view_host, opener_route_id, cross_process_frame_connector_); 1009 render_view_host, opener_route_id, proxy_routing_id,
1010 cross_process_frame_connector_);
989 } 1011 }
990 1012
991 void RenderFrameHostManager::CommitPending() { 1013 void RenderFrameHostManager::CommitPending() {
992 // First check whether we're going to want to focus the location bar after 1014 // First check whether we're going to want to focus the location bar after
993 // this commit. We do this now because the navigation hasn't formally 1015 // this commit. We do this now because the navigation hasn't formally
994 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 1016 // committed yet, so if we've already cleared |pending_web_ui_| the call chain
995 // this triggers won't be able to figure out what's going on. 1017 // this triggers won't be able to figure out what's going on.
996 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 1018 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
997 1019
998 // We expect SwapOutOldPage to have canceled any modal dialogs and told the 1020 // We expect SwapOutOldPage to have canceled any modal dialogs and told the
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 } 1120 }
1099 1121
1100 // If the old RFH is live, we are swapping it out and should keep track of 1122 // If the old RFH is live, we are swapping it out and should keep track of
1101 // it in case we navigate back to it, or it is waiting for the unload event 1123 // it in case we navigate back to it, or it is waiting for the unload event
1102 // to execute in the background. 1124 // to execute in the background.
1103 // TODO(creis): Swap out the subframe in --site-per-process. 1125 // TODO(creis): Swap out the subframe in --site-per-process.
1104 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) 1126 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess))
1105 DCHECK(old_render_frame_host->is_swapped_out() || 1127 DCHECK(old_render_frame_host->is_swapped_out() ||
1106 !RenderViewHostImpl::IsRVHStateActive( 1128 !RenderViewHostImpl::IsRVHStateActive(
1107 old_render_frame_host->render_view_host()->rvh_state())); 1129 old_render_frame_host->render_view_host()->rvh_state()));
1108 // Temp fix for http://crbug.com/90867 until we do a better cleanup to make
1109 // sure we don't get different rvh instances for the same site instance
1110 // in the same rvhmgr.
1111 // TODO(creis): Clean this up.
1112 RenderFrameProxyHostMap::iterator iter =
1113 proxy_hosts_.find(old_site_instance_id);
1114 if (iter != proxy_hosts_.end() &&
1115 iter->second->render_frame_host() != old_render_frame_host) {
1116 // Delete the proxy that will be replaced in the map to avoid a leak.
1117 delete iter->second;
1118 }
1119 1130
1120 // If the RenderViewHost backing the RenderFrameHost is pending shutdown, 1131 // If the RenderViewHost backing the RenderFrameHost is pending shutdown,
1121 // the RenderFrameHost should be put in the map of RenderFrameHosts pending 1132 // the RenderFrameHost should be put in the map of RenderFrameHosts pending
1122 // shutdown. Otherwise, it is stored in the map of proxy hosts. 1133 // shutdown. Otherwise, it is stored in the map of proxy hosts.
1123 if (old_render_frame_host->render_view_host()->rvh_state() == 1134 if (old_render_frame_host->render_view_host()->rvh_state() ==
1124 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) { 1135 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) {
1125 proxy_hosts_.erase(old_site_instance_id); 1136 // The proxy for this RenderFrameHost is created when sending the
1137 // SwapOut message, so check if it already exists and delete it.
1138 RenderFrameProxyHostMap::iterator iter =
1139 proxy_hosts_.find(old_site_instance_id);
1140 if (iter != proxy_hosts_.end()) {
1141 delete iter->second;
1142 proxy_hosts_.erase(iter);
1143 }
1126 RFHPendingDeleteMap::iterator pending_delete_iter = 1144 RFHPendingDeleteMap::iterator pending_delete_iter =
1127 pending_delete_hosts_.find(old_site_instance_id); 1145 pending_delete_hosts_.find(old_site_instance_id);
1128 if (pending_delete_iter == pending_delete_hosts_.end() || 1146 if (pending_delete_iter == pending_delete_hosts_.end() ||
1129 pending_delete_iter->second.get() != old_render_frame_host) { 1147 pending_delete_iter->second.get() != old_render_frame_host) {
1130 pending_delete_hosts_[old_site_instance_id] = 1148 pending_delete_hosts_[old_site_instance_id] =
1131 linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release()); 1149 linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release());
1132 } 1150 }
1133 } else { 1151 } else {
1152 // Capture the active view count on the old RFH SiteInstance, since the
1153 // ownership will be passed into the proxy and the pointer will be invalid.
1154 int active_view_count =
1155 static_cast<SiteInstanceImpl*>(old_render_frame_host->GetSiteInstance())
1156 ->active_view_count();
1157
1158 RenderFrameProxyHostMap::iterator iter =
1159 proxy_hosts_.find(old_site_instance_id);
1160 CHECK(iter != proxy_hosts_.end());
1161 iter->second->TakeFrameHostOwnership(old_render_frame_host.Pass());
1162
1134 // If there are no active views in this SiteInstance, it means that 1163 // If there are no active views in this SiteInstance, it means that
1135 // this RFH was the last active one in the SiteInstance. Now that we 1164 // this RFH was the last active one in the SiteInstance. Now that we
1136 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs 1165 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs
1137 // in this SiteInstance. We do this after ensuring the RFH is on the 1166 // in this SiteInstance.
1138 // swapped out list to simplify the deletion. 1167 if (!active_view_count)
1139 if (!static_cast<SiteInstanceImpl*>(
1140 old_render_frame_host->GetSiteInstance())->active_view_count()) {
1141 old_render_frame_host.reset();
1142 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); 1168 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id);
1143 } else {
1144 proxy_hosts_[old_site_instance_id] = new RenderFrameProxyHost(
1145 old_render_frame_host.Pass());
1146 }
1147 } 1169 }
1148 } 1170 }
1149 1171
1150 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance( 1172 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance(
1151 int32 site_instance_id) { 1173 int32 site_instance_id) {
1152 // First remove any swapped out RFH for this SiteInstance from our own list. 1174 // First remove any swapped out RFH for this SiteInstance from our own list.
1153 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); 1175 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_);
1154 1176
1155 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts 1177 // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts
1156 // in the SiteInstance, then tell their respective FrameTrees to remove all 1178 // in the SiteInstance, then tell their respective FrameTrees to remove all
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 pending_render_frame_host->GetProcess()->RemovePendingView(); 1370 pending_render_frame_host->GetProcess()->RemovePendingView();
1349 1371
1350 // If the SiteInstance for the pending RFH is being used by others, don't 1372 // If the SiteInstance for the pending RFH is being used by others, don't
1351 // delete the RFH, just swap it out and it can be reused at a later point. 1373 // delete the RFH, just swap it out and it can be reused at a later point.
1352 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>( 1374 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>(
1353 pending_render_frame_host->GetSiteInstance()); 1375 pending_render_frame_host->GetSiteInstance());
1354 if (site_instance->active_view_count() > 1) { 1376 if (site_instance->active_view_count() > 1) {
1355 // Any currently suspended navigations are no longer needed. 1377 // Any currently suspended navigations are no longer needed.
1356 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); 1378 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations();
1357 1379
1358 pending_render_frame_host->SwapOut(); 1380 RenderFrameProxyHost* proxy =
1359 1381 new RenderFrameProxyHost(site_instance, frame_tree_node_);
1360 proxy_hosts_[site_instance->GetId()] = new RenderFrameProxyHost( 1382 proxy_hosts_[site_instance->GetId()] = proxy;
1361 pending_render_frame_host.Pass()); 1383 pending_render_frame_host->SwapOut(proxy);
1384 proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass());
1362 } else { 1385 } else {
1363 // We won't be coming back, so delete this one. 1386 // We won't be coming back, so delete this one.
1364 pending_render_frame_host.reset(); 1387 pending_render_frame_host.reset();
1365 } 1388 }
1366 1389
1367 pending_web_ui_.reset(); 1390 pending_web_ui_.reset();
1368 pending_and_current_web_ui_.reset(); 1391 pending_and_current_web_ui_.reset();
1369 } 1392 }
1370 1393
1371 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( 1394 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 if (iter == proxy_hosts_.end()) 1435 if (iter == proxy_hosts_.end())
1413 return false; 1436 return false;
1414 1437
1415 return iter->second->render_frame_host() == rfh; 1438 return iter->second->render_frame_host() == rfh;
1416 } 1439 }
1417 1440
1418 RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost( 1441 RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost(
1419 SiteInstance* instance) const { 1442 SiteInstance* instance) const {
1420 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); 1443 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
1421 if (proxy) 1444 if (proxy)
1422 return proxy->render_view_host(); 1445 return proxy->GetRenderViewHost();
1423 return NULL; 1446 return NULL;
1424 } 1447 }
1425 1448
1426 RenderFrameProxyHost* RenderFrameHostManager::GetRenderFrameProxyHost( 1449 RenderFrameProxyHost* RenderFrameHostManager::GetRenderFrameProxyHost(
1427 SiteInstance* instance) const { 1450 SiteInstance* instance) const {
1428 RenderFrameProxyHostMap::const_iterator iter = 1451 RenderFrameProxyHostMap::const_iterator iter =
1429 proxy_hosts_.find(instance->GetId()); 1452 proxy_hosts_.find(instance->GetId());
1430 if (iter != proxy_hosts_.end()) 1453 if (iter != proxy_hosts_.end())
1431 return iter->second; 1454 return iter->second;
1432 1455
1433 return NULL; 1456 return NULL;
1434 } 1457 }
1435 1458
1436 } // namespace content 1459 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698