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

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

Powered by Google App Engine
This is Rietveld 408576698