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

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

Issue 88503002: Have the unload event execute in background on cross-site navigations (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Keeping the old rvh alive for up to 1s Created 7 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 | 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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 218
219 // If the tab becomes unresponsive during {before}unload while doing a 219 // If the tab becomes unresponsive during {before}unload while doing a
220 // cross-site navigation, proceed with the navigation. (This assumes that 220 // cross-site navigation, proceed with the navigation. (This assumes that
221 // the pending RenderViewHost is still responsive.) 221 // the pending RenderViewHost is still responsive.)
222 if (render_view_host_->is_waiting_for_unload_ack()) { 222 if (render_view_host_->is_waiting_for_unload_ack()) {
223 // The request has been started and paused while we're waiting for the 223 // The request has been started and paused while we're waiting for the
224 // unload handler to finish. We'll pretend that it did. The pending 224 // unload handler to finish. We'll pretend that it did. The pending
225 // renderer will then be swapped in as part of the usual DidNavigate logic. 225 // renderer will then be swapped in as part of the usual DidNavigate logic.
226 // (If the unload handler later finishes, this call will be ignored because 226 // (If the unload handler later finishes, this call will be ignored because
227 // the pending_nav_params_ state will already be cleaned up.) 227 // the pending_nav_params_ state will already be cleaned up.)
228 current_host()->OnSwappedOut(true); 228 current_host()->OnSwappedOut(true, false);
229 } else if (render_view_host_->is_waiting_for_beforeunload_ack()) { 229 } else if (render_view_host_->is_waiting_for_beforeunload_ack()) {
230 // Haven't gotten around to starting the request, because we're still 230 // Haven't gotten around to starting the request, because we're still
231 // waiting for the beforeunload handler to finish. We'll pretend that it 231 // waiting for the beforeunload handler to finish. We'll pretend that it
232 // did finish, to let the navigation proceed. Note that there's a danger 232 // did finish, to let the navigation proceed. Note that there's a danger
233 // that the beforeunload handler will later finish and possibly return 233 // that the beforeunload handler will later finish and possibly return
234 // false (meaning the navigation should not proceed), but we'll ignore it 234 // false (meaning the navigation should not proceed), but we'll ignore it
235 // in this case because it took too long. 235 // in this case because it took too long.
236 if (pending_render_view_host_->are_navigations_suspended()) 236 if (pending_render_view_host_->are_navigations_suspended())
237 pending_render_view_host_->SetNavigationsSuspended( 237 pending_render_view_host_->SetNavigationsSuspended(
238 false, base::TimeTicks::Now()); 238 false, base::TimeTicks::Now());
239 } 239 }
240 return false; 240 return false;
241 } 241 }
242 242
243 void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) { 243 void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) {
244 // Make sure this is from our current RVH, and that we have a pending 244 // Make sure this is from our current RVH, and that we have a pending
245 // navigation from OnCrossSiteResponse. (There may be no pending navigation 245 // navigation from OnCrossSiteResponse. (There may be no pending navigation
246 // for data URLs that don't make network requests, for example.) If not, 246 // for data URLs that don't make network requests, for example.) If not,
247 // just return early and ignore. 247 // it may be coming from an earlier RVH that was left to wait for the
248 // execution of the unload event in the background.
248 if (render_view_host != render_view_host_ || !pending_nav_params_.get()) { 249 if (render_view_host != render_view_host_ || !pending_nav_params_.get()) {
250 RenderViewHostImpl* render_view_host_impl =
251 static_cast<RenderViewHostImpl*>(render_view_host);
252 if (!static_cast<SiteInstanceImpl*>(
253 render_view_host_impl->GetSiteInstance())->active_view_count() &&
254 !render_view_host_impl->should_be_preserved_on_swap_out()) {
255 ShutdownRenderViewHostsInSiteInstance(
256 render_view_host_impl->GetSiteInstance()->GetId());
257 // This is deleted while cleaning up the SiteInstance's views.
258 render_view_host_impl = NULL;
259 }
249 pending_nav_params_.reset(); 260 pending_nav_params_.reset();
250 return; 261 return;
251 } 262 }
252 263
253 // Now that the unload handler has run, we need to either initiate the 264 // Now that the unload handler has run, we need to either initiate the
254 // pending transfer (if there is one) or resume the paused response (if not). 265 // pending transfer (if there is one) or resume the paused response (if not).
255 // TODO(creis): The blank swapped out page is visible during this time, but 266 // TODO(creis): The blank swapped out page is visible during this time, but
256 // we can shorten this by delivering the response directly, rather than 267 // we can shorten this by delivering the response directly, rather than
257 // forcing an identical request to be made. 268 // forcing an identical request to be made.
258 if (pending_nav_params_->is_transfer) { 269 if (pending_nav_params_->is_transfer) {
(...skipping 10 matching lines...) Expand all
269 transfer_url, 280 transfer_url,
270 pending_nav_params_->transfer_url_chain, 281 pending_nav_params_->transfer_url_chain,
271 pending_nav_params_->referrer, 282 pending_nav_params_->referrer,
272 pending_nav_params_->page_transition, 283 pending_nav_params_->page_transition,
273 CURRENT_TAB, 284 CURRENT_TAB,
274 pending_nav_params_->frame_id, 285 pending_nav_params_->frame_id,
275 pending_nav_params_->global_request_id, 286 pending_nav_params_->global_request_id,
276 pending_nav_params_->should_replace_current_entry, 287 pending_nav_params_->should_replace_current_entry,
277 true); 288 true);
278 } else if (pending_render_view_host_) { 289 } else if (pending_render_view_host_) {
279 RenderProcessHostImpl* pending_process = 290 pending_render_view_host_->GetProcess()->ResumeDeferredNavigation(
280 static_cast<RenderProcessHostImpl*>(
281 pending_render_view_host_->GetProcess());
282 pending_process->ResumeDeferredNavigation(
283 pending_nav_params_->global_request_id); 291 pending_nav_params_->global_request_id);
284 } 292 }
285 pending_nav_params_.reset(); 293 pending_nav_params_.reset();
286 } 294 }
287 295
288 void RenderFrameHostManager::DidNavigateMainFrame( 296 void RenderFrameHostManager::DidNavigateMainFrame(
289 RenderViewHost* render_view_host) { 297 RenderViewHost* render_view_host) {
290 if (!cross_navigation_pending_) { 298 if (!cross_navigation_pending_) {
291 DCHECK(!pending_render_view_host_); 299 DCHECK(!pending_render_view_host_);
292 300
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 delegate_->NotifySwappedFromRenderManager(old_render_view_host, 882 delegate_->NotifySwappedFromRenderManager(old_render_view_host,
875 render_view_host_); 883 render_view_host_);
876 884
877 // If the pending view was on the swapped out list, we can remove it. 885 // If the pending view was on the swapped out list, we can remove it.
878 swapped_out_hosts_.erase(render_view_host_->GetSiteInstance()->GetId()); 886 swapped_out_hosts_.erase(render_view_host_->GetSiteInstance()->GetId());
879 887
880 // If there are no active RVHs in this SiteInstance, it means that 888 // If there are no active RVHs in this SiteInstance, it means that
881 // this RVH was the last active one in the SiteInstance. Now that we 889 // this RVH was the last active one in the SiteInstance. Now that we
882 // know that all RVHs are swapped out, we can delete all the RVHs in 890 // know that all RVHs are swapped out, we can delete all the RVHs in
883 // this SiteInstance. 891 // this SiteInstance.
884 if (!static_cast<SiteInstanceImpl*>(old_render_view_host->GetSiteInstance())-> 892 if (!static_cast<SiteInstanceImpl*>(old_render_view_host->GetSiteInstance())
885 active_view_count()) { 893 ->active_view_count() &&
Charlie Reis 2013/12/09 20:12:29 nit: Please keep the arrow at the end of the line,
894 !old_render_view_host->should_be_preserved_on_swap_out()) {
Charlie Reis 2013/12/09 20:12:29 I'd like to avoid adding this here if possible.
886 ShutdownRenderViewHostsInSiteInstance( 895 ShutdownRenderViewHostsInSiteInstance(
887 old_render_view_host->GetSiteInstance()->GetId()); 896 old_render_view_host->GetSiteInstance()->GetId());
888 // This is deleted while cleaning up the SitaInstance's views. 897 // This is deleted while cleaning up the SiteInstance's views.
889 old_render_view_host = NULL; 898 old_render_view_host = NULL;
890 } else if (old_render_view_host->IsRenderViewLive()) { 899 } else if (old_render_view_host->IsRenderViewLive() ||
900 old_render_view_host->should_be_preserved_on_swap_out()) {
891 // If the old RVH is live, we are swapping it out and should keep track of 901 // If the old RVH is live, we are swapping it out and should keep track of
892 // it in case we navigate back to it. 902 // it in case we navigate back to it.
893 DCHECK(old_render_view_host->is_swapped_out()); 903 DCHECK(old_render_view_host->is_swapped_out());
894 // Temp fix for http://crbug.com/90867 until we do a better cleanup to make 904 // Temp fix for http://crbug.com/90867 until we do a better cleanup to make
895 // sure we don't get different rvh instances for the same site instance 905 // sure we don't get different rvh instances for the same site instance
896 // in the same rvhmgr. 906 // in the same rvhmgr.
897 // TODO(creis): Clean this up. 907 // TODO(creis): Clean this up.
898 int32 old_site_instance_id = 908 int32 old_site_instance_id =
899 old_render_view_host->GetSiteInstance()->GetId(); 909 old_render_view_host->GetSiteInstance()->GetId();
900 RenderViewHostMap::iterator iter = 910 RenderViewHostMap::iterator iter =
(...skipping 16 matching lines...) Expand all
917 // list. 927 // list.
918 swapped_out_hosts_.erase(site_instance_id); 928 swapped_out_hosts_.erase(site_instance_id);
919 929
920 scoped_ptr<RenderWidgetHostIterator> widgets( 930 scoped_ptr<RenderWidgetHostIterator> widgets(
921 RenderWidgetHostImpl::GetAllRenderWidgetHosts()); 931 RenderWidgetHostImpl::GetAllRenderWidgetHosts());
922 while (RenderWidgetHost* widget = widgets->GetNextHost()) { 932 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
923 if (!widget->IsRenderView()) 933 if (!widget->IsRenderView())
924 continue; 934 continue;
925 RenderViewHostImpl* rvh = 935 RenderViewHostImpl* rvh =
926 static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget)); 936 static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget));
927 if (site_instance_id == rvh->GetSiteInstance()->GetId()) 937 if (site_instance_id == rvh->GetSiteInstance()->GetId()) {
938 // If the RVH was waiting for the unload event to execute in the
939 // background, it may not have completely cleaned up its state yet.
940 if (rvh->need_to_perform_clean_up_on_swapped_out()) {
941 rvh->WasSwappedOut();
942 }
928 rvh->Shutdown(); 943 rvh->Shutdown();
944 }
929 } 945 }
930 } 946 }
931 947
932 RenderViewHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate( 948 RenderViewHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate(
933 const NavigationEntryImpl& entry) { 949 const NavigationEntryImpl& entry) {
934 // If we are currently navigating cross-process, we want to get back to normal 950 // If we are currently navigating cross-process, we want to get back to normal
935 // and then navigate as usual. 951 // and then navigate as usual.
936 if (cross_navigation_pending_) { 952 if (cross_navigation_pending_) {
937 if (pending_render_view_host_) 953 if (pending_render_view_host_)
938 CancelPending(); 954 CancelPending();
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost( 1169 RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost(
1154 SiteInstance* instance) { 1170 SiteInstance* instance) {
1155 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId()); 1171 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId());
1156 if (iter != swapped_out_hosts_.end()) 1172 if (iter != swapped_out_hosts_.end())
1157 return iter->second; 1173 return iter->second;
1158 1174
1159 return NULL; 1175 return NULL;
1160 } 1176 }
1161 1177
1162 } // namespace content 1178 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698