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

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

Issue 180993003: Revert "Revert 249676 "Have the unload event execute in background on cr..."" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Delete RFH pending shutdown in all nodes of the FrameTree Created 6 years, 9 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/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 cross_site_transferring_request(cross_site_transferring_request.Pass()), 50 cross_site_transferring_request(cross_site_transferring_request.Pass()),
51 transfer_url_chain(transfer_url_chain), 51 transfer_url_chain(transfer_url_chain),
52 referrer(referrer), 52 referrer(referrer),
53 page_transition(page_transition), 53 page_transition(page_transition),
54 frame_id(frame_id), 54 frame_id(frame_id),
55 should_replace_current_entry(should_replace_current_entry) { 55 should_replace_current_entry(should_replace_current_entry) {
56 } 56 }
57 57
58 RenderFrameHostManager::PendingNavigationParams::~PendingNavigationParams() {} 58 RenderFrameHostManager::PendingNavigationParams::~PendingNavigationParams() {}
59 59
60 bool RenderFrameHostManager::ClearRFHsPendingShutdown(FrameTreeNode* node) {
61 node->render_manager()->pending_delete_hosts_.clear();
62 return true;
63 }
64
60 RenderFrameHostManager::RenderFrameHostManager( 65 RenderFrameHostManager::RenderFrameHostManager(
61 FrameTreeNode* frame_tree_node, 66 FrameTreeNode* frame_tree_node,
62 RenderFrameHostDelegate* render_frame_delegate, 67 RenderFrameHostDelegate* render_frame_delegate,
63 RenderViewHostDelegate* render_view_delegate, 68 RenderViewHostDelegate* render_view_delegate,
64 RenderWidgetHostDelegate* render_widget_delegate, 69 RenderWidgetHostDelegate* render_widget_delegate,
65 Delegate* delegate) 70 Delegate* delegate)
66 : frame_tree_node_(frame_tree_node), 71 : frame_tree_node_(frame_tree_node),
67 delegate_(delegate), 72 delegate_(delegate),
68 cross_navigation_pending_(false), 73 cross_navigation_pending_(false),
69 render_frame_delegate_(render_frame_delegate), 74 render_frame_delegate_(render_frame_delegate),
70 render_view_delegate_(render_view_delegate), 75 render_view_delegate_(render_view_delegate),
71 render_widget_delegate_(render_widget_delegate), 76 render_widget_delegate_(render_widget_delegate),
72 render_frame_host_(NULL), 77 render_frame_host_(NULL),
73 pending_render_frame_host_(NULL), 78 pending_render_frame_host_(NULL),
74 interstitial_page_(NULL), 79 interstitial_page_(NULL),
75 cross_process_frame_connector_(NULL) {} 80 cross_process_frame_connector_(NULL),
81 weak_factory_(this) {}
76 82
77 RenderFrameHostManager::~RenderFrameHostManager() { 83 RenderFrameHostManager::~RenderFrameHostManager() {
78 if (pending_render_frame_host_) 84 if (pending_render_frame_host_)
79 CancelPending(); 85 CancelPending();
80 86
81 if (cross_process_frame_connector_) 87 if (cross_process_frame_connector_)
82 delete cross_process_frame_connector_; 88 delete cross_process_frame_connector_;
83 89
84 // We should always have a current RenderFrameHost except in some tests. 90 // We should always have a current RenderFrameHost except in some tests.
85 // TODO(creis): Now that we aren't using Shutdown, make render_frame_host_ and 91 // TODO(creis): Now that we aren't using Shutdown, make render_frame_host_ and
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 if (!cross_navigation_pending_) 242 if (!cross_navigation_pending_)
237 return true; 243 return true;
238 244
239 // We should always have a pending RFH when there's a cross-process navigation 245 // We should always have a pending RFH when there's a cross-process navigation
240 // in progress. Sanity check this for http://crbug.com/276333. 246 // in progress. Sanity check this for http://crbug.com/276333.
241 CHECK(pending_render_frame_host_); 247 CHECK(pending_render_frame_host_);
242 248
243 // If the tab becomes unresponsive during {before}unload while doing a 249 // If the tab becomes unresponsive during {before}unload while doing a
244 // cross-site navigation, proceed with the navigation. (This assumes that 250 // cross-site navigation, proceed with the navigation. (This assumes that
245 // the pending RenderFrameHost is still responsive.) 251 // the pending RenderFrameHost is still responsive.)
246 if (render_frame_host_->render_view_host()->is_waiting_for_unload_ack()) { 252 if (render_frame_host_->render_view_host()->IsWaitingForUnloadACK()) {
247 // The request has been started and paused while we're waiting for the 253 // The request has been started and paused while we're waiting for the
248 // unload handler to finish. We'll pretend that it did. The pending 254 // unload handler to finish. We'll pretend that it did. The pending
249 // renderer will then be swapped in as part of the usual DidNavigate logic. 255 // renderer will then be swapped in as part of the usual DidNavigate logic.
250 // (If the unload handler later finishes, this call will be ignored because 256 // (If the unload handler later finishes, this call will be ignored because
251 // the pending_nav_params_ state will already be cleaned up.) 257 // the pending_nav_params_ state will already be cleaned up.)
252 current_host()->OnSwappedOut(true); 258 current_host()->OnSwappedOut(true);
253 } else if (render_frame_host_->render_view_host()-> 259 } else if (render_frame_host_->render_view_host()->
254 is_waiting_for_beforeunload_ack()) { 260 is_waiting_for_beforeunload_ack()) {
255 // Haven't gotten around to starting the request, because we're still 261 // Haven't gotten around to starting the request, because we're still
256 // waiting for the beforeunload handler to finish. We'll pretend that it 262 // waiting for the beforeunload handler to finish. We'll pretend that it
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 // ResourceDispatcherHost has told us to run the onunload handler, which 563 // ResourceDispatcherHost has told us to run the onunload handler, which
558 // means it is not a download or unsafe page, and we are going to perform the 564 // means it is not a download or unsafe page, and we are going to perform the
559 // navigation. Thus, we no longer need to remember that the RenderFrameHost 565 // navigation. Thus, we no longer need to remember that the RenderFrameHost
560 // is part of a pending cross-site request. 566 // is part of a pending cross-site request.
561 if (pending_render_frame_host_) { 567 if (pending_render_frame_host_) {
562 pending_render_frame_host_->render_view_host()-> 568 pending_render_frame_host_->render_view_host()->
563 SetHasPendingCrossSiteRequest(false); 569 SetHasPendingCrossSiteRequest(false);
564 } 570 }
565 } 571 }
566 572
573 void RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance(
574 int32 site_instance_id,
575 RenderFrameHostImpl* rfh) {
576 RFHPendingDeleteMap::iterator iter =
577 pending_delete_hosts_.find(site_instance_id);
578 if (iter != pending_delete_hosts_.end() && iter->second.get() == rfh)
579 pending_delete_hosts_.erase(site_instance_id);
580 }
581
567 void RenderFrameHostManager::Observe( 582 void RenderFrameHostManager::Observe(
568 int type, 583 int type,
569 const NotificationSource& source, 584 const NotificationSource& source,
570 const NotificationDetails& details) { 585 const NotificationDetails& details) {
571 switch (type) { 586 switch (type) {
572 case NOTIFICATION_RENDERER_PROCESS_CLOSED: 587 case NOTIFICATION_RENDERER_PROCESS_CLOSED:
573 case NOTIFICATION_RENDERER_PROCESS_CLOSING: 588 case NOTIFICATION_RENDERER_PROCESS_CLOSING:
574 RendererProcessClosing( 589 RendererProcessClosing(
575 Source<RenderProcessHost>(source).ptr()); 590 Source<RenderProcessHost>(source).ptr());
576 break; 591 break;
577 592
578 default: 593 default:
579 NOTREACHED(); 594 NOTREACHED();
580 } 595 }
581 } 596 }
582 597
583 bool RenderFrameHostManager::ClearSwappedOutRFHsInSiteInstance( 598 bool RenderFrameHostManager::ClearSwappedOutRFHsInSiteInstance(
584 int32 site_instance_id, 599 int32 site_instance_id,
585 FrameTreeNode* node) { 600 FrameTreeNode* node) {
586 RenderFrameHostMap::iterator iter = 601 RenderFrameHostMap::iterator iter =
587 node->render_manager()->swapped_out_hosts_.find(site_instance_id); 602 node->render_manager()->swapped_out_hosts_.find(site_instance_id);
588 if (iter != node->render_manager()->swapped_out_hosts_.end()) 603 if (iter != node->render_manager()->swapped_out_hosts_.end()) {
589 delete iter->second; 604 RenderFrameHostImpl* swapped_out_rfh = iter->second;
605 // If the RVH is pending swap out, it needs to switch state to
606 // pending shutdown. Otherwise it is deleted.
607 if (swapped_out_rfh->render_view_host()->rvh_state() ==
608 RenderViewHostImpl::STATE_PENDING_SWAP_OUT) {
609 swapped_out_rfh->SetPendingShutdown(base::Bind(
610 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance,
611 node->render_manager()->weak_factory_.GetWeakPtr(),
612 site_instance_id,
613 swapped_out_rfh));
614 RFHPendingDeleteMap::iterator pending_delete_iter =
615 node->render_manager()->pending_delete_hosts_.find(site_instance_id);
616 if (pending_delete_iter ==
617 node->render_manager()->pending_delete_hosts_.end() ||
618 pending_delete_iter->second.get() != iter->second) {
619 node->render_manager()->pending_delete_hosts_[site_instance_id] =
620 linked_ptr<RenderFrameHostImpl>(swapped_out_rfh);
621 }
622 } else {
623 delete swapped_out_rfh;
624 }
625 node->render_manager()->swapped_out_hosts_.erase(site_instance_id);
626 }
590 627
591 return true; 628 return true;
592 } 629 }
593 630
594 bool RenderFrameHostManager::ShouldTransitionCrossSite() { 631 bool RenderFrameHostManager::ShouldTransitionCrossSite() {
595 // False in the single-process mode, as it makes RVHs to accumulate 632 // False in the single-process mode, as it makes RVHs to accumulate
596 // in swapped_out_hosts_. 633 // in swapped_out_hosts_.
597 // True if we are using process-per-site-instance (default) or 634 // True if we are using process-per-site-instance (default) or
598 // process-per-site (kProcessPerSite). 635 // process-per-site (kProcessPerSite).
599 return 636 return
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 // If the pending navigation is to a WebUI and the RenderView is not in a 999 // If the pending navigation is to a WebUI and the RenderView is not in a
963 // guest process, tell the RenderViewHost about any bindings it will need 1000 // guest process, tell the RenderViewHost about any bindings it will need
964 // enabled. 1001 // enabled.
965 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) { 1002 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) {
966 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 1003 render_view_host->AllowBindings(pending_web_ui()->GetBindings());
967 } else { 1004 } else {
968 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled 1005 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
969 // process unless it's swapped out. 1006 // process unless it's swapped out.
970 RenderViewHostImpl* rvh_impl = 1007 RenderViewHostImpl* rvh_impl =
971 static_cast<RenderViewHostImpl*>(render_view_host); 1008 static_cast<RenderViewHostImpl*>(render_view_host);
972 if (!rvh_impl->is_swapped_out()) { 1009 if (!rvh_impl->IsSwappedOut()) {
973 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 1010 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
974 render_view_host->GetProcess()->GetID())); 1011 render_view_host->GetProcess()->GetID()));
975 } 1012 }
976 } 1013 }
977 1014
978 return delegate_->CreateRenderViewForRenderManager( 1015 return delegate_->CreateRenderViewForRenderManager(
979 render_view_host, opener_route_id, cross_process_frame_connector_); 1016 render_view_host, opener_route_id, cross_process_frame_connector_);
980 } 1017 }
981 1018
982 void RenderFrameHostManager::CommitPending() { 1019 void RenderFrameHostManager::CommitPending() {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 // to make sure the sad tab shows up, etc. 1078 // to make sure the sad tab shows up, etc.
1042 if (!render_frame_host_->render_view_host()->GetView()) { 1079 if (!render_frame_host_->render_view_host()->GetView()) {
1043 delegate_->RenderProcessGoneFromRenderManager( 1080 delegate_->RenderProcessGoneFromRenderManager(
1044 render_frame_host_->render_view_host()); 1081 render_frame_host_->render_view_host());
1045 } else if (!delegate_->IsHidden()) { 1082 } else if (!delegate_->IsHidden()) {
1046 render_frame_host_->render_view_host()->GetView()->Show(); 1083 render_frame_host_->render_view_host()->GetView()->Show();
1047 } 1084 }
1048 1085
1049 // If the old view is live and top-level, hide it now that the new one is 1086 // If the old view is live and top-level, hide it now that the new one is
1050 // visible. 1087 // visible.
1088 int32 old_site_instance_id =
1089 old_render_frame_host->render_view_host()->GetSiteInstance()->GetId();
1051 if (old_render_frame_host->render_view_host()->GetView()) { 1090 if (old_render_frame_host->render_view_host()->GetView()) {
1052 if (is_main_frame) { 1091 if (is_main_frame) {
1053 old_render_frame_host->render_view_host()->GetView()->Hide(); 1092 old_render_frame_host->render_view_host()->GetView()->Hide();
1054 old_render_frame_host->render_view_host()->WasSwappedOut(); 1093 old_render_frame_host->render_view_host()->WasSwappedOut(base::Bind(
1094 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance,
1095 weak_factory_.GetWeakPtr(),
1096 old_site_instance_id,
1097 old_render_frame_host));
1055 } else { 1098 } else {
1056 // TODO(creis): We'll need to set this back to false if we navigate back. 1099 // TODO(creis): We'll need to set this back to false if we navigate back.
1057 old_render_frame_host->set_swapped_out(true); 1100 old_render_frame_host->set_swapped_out(true);
1058 } 1101 }
1059 } 1102 }
1060 1103
1061 // Make sure the size is up to date. (Fix for bug 1079768.) 1104 // Make sure the size is up to date. (Fix for bug 1079768.)
1062 delegate_->UpdateRenderViewSizeForRenderManager(); 1105 delegate_->UpdateRenderViewSizeForRenderManager();
1063 1106
1064 if (will_focus_location_bar) { 1107 if (will_focus_location_bar) {
(...skipping 13 matching lines...) Expand all
1078 old_render_frame_host->render_view_host(), 1121 old_render_frame_host->render_view_host(),
1079 render_frame_host_->render_view_host()); 1122 render_frame_host_->render_view_host());
1080 } 1123 }
1081 1124
1082 // If the pending frame was on the swapped out list, we can remove it. 1125 // If the pending frame was on the swapped out list, we can remove it.
1083 swapped_out_hosts_.erase(render_frame_host_->render_view_host()-> 1126 swapped_out_hosts_.erase(render_frame_host_->render_view_host()->
1084 GetSiteInstance()->GetId()); 1127 GetSiteInstance()->GetId());
1085 1128
1086 if (old_render_frame_host->render_view_host()->IsRenderViewLive()) { 1129 if (old_render_frame_host->render_view_host()->IsRenderViewLive()) {
1087 // If the old RFH is live, we are swapping it out and should keep track of 1130 // If the old RFH is live, we are swapping it out and should keep track of
1088 // it in case we navigate back to it. 1131 // it in case we navigate back to it, or it is waiting for the unload event
1132 // to execute in the background.
1089 // TODO(creis): Swap out the subframe in --site-per-process. 1133 // TODO(creis): Swap out the subframe in --site-per-process.
1090 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) 1134 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess))
1091 DCHECK(old_render_frame_host->is_swapped_out() || 1135 DCHECK(old_render_frame_host->is_swapped_out() ||
1092 old_render_frame_host->render_view_host()->is_swapped_out()); 1136 !RenderViewHostImpl::IsRVHStateActive(
1093 1137 old_render_frame_host->render_view_host()->rvh_state()));
1094 // Temp fix for http://crbug.com/90867 until we do a better cleanup to make 1138 // Temp fix for http://crbug.com/90867 until we do a better cleanup to make
1095 // sure we don't get different rvh instances for the same site instance 1139 // sure we don't get different rvh instances for the same site instance
1096 // in the same rvhmgr. 1140 // in the same rvhmgr.
1097 // TODO(creis): Clean this up. 1141 // TODO(creis): Clean this up.
1098 int32 old_site_instance_id =
1099 old_render_frame_host->render_view_host()->GetSiteInstance()->GetId();
1100 RenderFrameHostMap::iterator iter = 1142 RenderFrameHostMap::iterator iter =
1101 swapped_out_hosts_.find(old_site_instance_id); 1143 swapped_out_hosts_.find(old_site_instance_id);
1102 if (iter != swapped_out_hosts_.end() && 1144 if (iter != swapped_out_hosts_.end() &&
1103 iter->second != old_render_frame_host) { 1145 iter->second != old_render_frame_host) {
1104 // Delete the RFH that will be replaced in the map to avoid a leak. 1146 // Delete the RFH that will be replaced in the map to avoid a leak.
1105 delete iter->second; 1147 delete iter->second;
1106 } 1148 }
1107 swapped_out_hosts_[old_site_instance_id] = old_render_frame_host; 1149 // If the RenderViewHost backing the RenderFrameHost is pending shutdown,
1150 // the RenderFrameHost should be put in the map of RenderFrameHosts pending
1151 // shutdown. Otherwise, it is stored in the map of swapped out
1152 // RenderFrameHosts.
1153 if (old_render_frame_host->render_view_host()->rvh_state() ==
1154 RenderViewHostImpl::STATE_PENDING_SHUTDOWN) {
1155 swapped_out_hosts_.erase(old_site_instance_id);
1156 RFHPendingDeleteMap::iterator pending_delete_iter =
1157 pending_delete_hosts_.find(old_site_instance_id);
1158 if (pending_delete_iter == pending_delete_hosts_.end() ||
1159 pending_delete_iter->second.get() != old_render_frame_host) {
1160 pending_delete_hosts_[old_site_instance_id] =
1161 linked_ptr<RenderFrameHostImpl>(old_render_frame_host);
1162 }
1163 } else {
1164 swapped_out_hosts_[old_site_instance_id] = old_render_frame_host;
1165 }
1108 1166
1109 // If there are no active views in this SiteInstance, it means that 1167 // If there are no active views in this SiteInstance, it means that
1110 // this RFH was the last active one in the SiteInstance. Now that we 1168 // this RFH was the last active one in the SiteInstance. Now that we
1111 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs 1169 // know that all RFHs are swapped out, we can delete all the RFHs and RVHs
1112 // in this SiteInstance. We do this after ensuring the RFH is on the 1170 // in this SiteInstance. We do this after ensuring the RFH is on the
1113 // swapped out list to simplify the deletion. 1171 // swapped out list to simplify the deletion.
1114 if (!static_cast<SiteInstanceImpl*>( 1172 if (!static_cast<SiteInstanceImpl*>(
1115 old_render_frame_host->render_view_host()->GetSiteInstance())-> 1173 old_render_frame_host->render_view_host()->GetSiteInstance())->
1116 active_view_count()) { 1174 active_view_count()) {
1117 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id); 1175 ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id);
(...skipping 22 matching lines...) Expand all
1140 continue; 1198 continue;
1141 RenderViewHostImpl* rvh = 1199 RenderViewHostImpl* rvh =
1142 static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget)); 1200 static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget));
1143 if (site_instance_id == rvh->GetSiteInstance()->GetId()) { 1201 if (site_instance_id == rvh->GetSiteInstance()->GetId()) {
1144 // This deletes all RenderFrameHosts using the |rvh|, which then causes 1202 // This deletes all RenderFrameHosts using the |rvh|, which then causes
1145 // |rvh| to Shutdown. 1203 // |rvh| to Shutdown.
1146 FrameTree* tree = rvh->GetDelegate()->GetFrameTree(); 1204 FrameTree* tree = rvh->GetDelegate()->GetFrameTree();
1147 tree->ForEach(base::Bind( 1205 tree->ForEach(base::Bind(
1148 &RenderFrameHostManager::ClearSwappedOutRFHsInSiteInstance, 1206 &RenderFrameHostManager::ClearSwappedOutRFHsInSiteInstance,
1149 site_instance_id)); 1207 site_instance_id));
1150 // rvh is now deleted.
1151 } 1208 }
1152 } 1209 }
1153 } 1210 }
1154 1211
1155 RenderFrameHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate( 1212 RenderFrameHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate(
1156 const NavigationEntryImpl& entry) { 1213 const NavigationEntryImpl& entry) {
1157 // If we are currently navigating cross-process, we want to get back to normal 1214 // If we are currently navigating cross-process, we want to get back to normal
1158 // and then navigate as usual. 1215 // and then navigate as usual.
1159 if (cross_navigation_pending_) { 1216 if (cross_navigation_pending_) {
1160 if (pending_render_frame_host_) 1217 if (pending_render_frame_host_)
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 SiteInstance* instance) const { 1466 SiteInstance* instance) const {
1410 RenderFrameHostMap::const_iterator iter = 1467 RenderFrameHostMap::const_iterator iter =
1411 swapped_out_hosts_.find(instance->GetId()); 1468 swapped_out_hosts_.find(instance->GetId());
1412 if (iter != swapped_out_hosts_.end()) 1469 if (iter != swapped_out_hosts_.end())
1413 return iter->second; 1470 return iter->second;
1414 1471
1415 return NULL; 1472 return NULL;
1416 } 1473 }
1417 1474
1418 } // namespace content 1475 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698