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

Side by Side Diff: content/browser/renderer_host/render_view_host_impl.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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/renderer_host/render_view_host_impl.h" 5 #include "content/browser/renderer_host/render_view_host_impl.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 enabled_bindings_(0), 175 enabled_bindings_(0),
176 navigations_suspended_(false), 176 navigations_suspended_(false),
177 has_accessed_initial_document_(false), 177 has_accessed_initial_document_(false),
178 is_swapped_out_(swapped_out), 178 is_swapped_out_(swapped_out),
179 is_subframe_(false), 179 is_subframe_(false),
180 main_frame_id_(-1), 180 main_frame_id_(-1),
181 run_modal_reply_msg_(NULL), 181 run_modal_reply_msg_(NULL),
182 run_modal_opener_id_(MSG_ROUTING_NONE), 182 run_modal_opener_id_(MSG_ROUTING_NONE),
183 is_waiting_for_beforeunload_ack_(false), 183 is_waiting_for_beforeunload_ack_(false),
184 is_waiting_for_unload_ack_(false), 184 is_waiting_for_unload_ack_(false),
185 should_be_preserved_on_swap_out_(false),
186 need_to_perform_clean_up_on_swapped_out_(false),
185 has_timed_out_on_unload_(false), 187 has_timed_out_on_unload_(false),
186 unload_ack_is_for_cross_site_transition_(false), 188 unload_ack_is_for_cross_site_transition_(false),
187 are_javascript_messages_suppressed_(false), 189 are_javascript_messages_suppressed_(false),
188 sudden_termination_allowed_(false), 190 sudden_termination_allowed_(false),
189 render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING) { 191 render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING) {
190 DCHECK(instance_.get()); 192 DCHECK(instance_.get());
191 CHECK(delegate_); // http://crbug.com/82827 193 CHECK(delegate_); // http://crbug.com/82827
192 194
193 if (main_frame_routing_id == MSG_ROUTING_NONE) 195 if (main_frame_routing_id == MSG_ROUTING_NONE)
194 main_frame_routing_id = GetProcess()->GetNextRoutingID(); 196 main_frame_routing_id = GetProcess()->GetNextRoutingID();
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 manager->OnCrossSiteResponse(this, global_request_id, is_transfer, 689 manager->OnCrossSiteResponse(this, global_request_id, is_transfer,
688 transfer_url_chain, referrer, page_transition, 690 transfer_url_chain, referrer, page_transition,
689 frame_id, should_replace_current_entry); 691 frame_id, should_replace_current_entry);
690 } 692 }
691 } 693 }
692 694
693 void RenderViewHostImpl::SuppressDialogsUntilSwapOut() { 695 void RenderViewHostImpl::SuppressDialogsUntilSwapOut() {
694 Send(new ViewMsg_SuppressDialogsUntilSwapOut(GetRoutingID())); 696 Send(new ViewMsg_SuppressDialogsUntilSwapOut(GetRoutingID()));
695 } 697 }
696 698
697 void RenderViewHostImpl::SwapOut() { 699 void RenderViewHostImpl::SwapOut() {
Charlie Reis 2013/12/09 20:12:29 I don't think we need most of this method, and we
698 // This will be set back to false in OnSwapOutACK, just before we replace 700 // This will be set back to false in OnSwapOutACK, just before we replace
699 // this RVH with the pending RVH. 701 // this RVH with the pending RVH.
700 is_waiting_for_unload_ack_ = true; 702 is_waiting_for_unload_ack_ = true;
701 // Start the hang monitor in case the renderer hangs in the unload handler. 703 // Start a timer to kill the renderer if the unload event takes too long to
702 // Increment the in-flight event count, to ensure that input events won't 704 // execute in the background.
703 // cancel the timeout timer. 705 // http://crbug.com/323528.
704 increment_in_flight_event_count(); 706 increment_in_flight_event_count();
705 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); 707 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS));
706 708
709 // If the RenderViewHost doesn't have a live renderer, the unload event is
710 // skipped. Otherwise, the RenderViewHost will remain alive until the unload
711 // event has finished executing in the background (or timed out).
712 bool preserve_render_view_host = false;
713 bool timed_out = true;
707 if (IsRenderViewLive()) { 714 if (IsRenderViewLive()) {
708 Send(new ViewMsg_SwapOut(GetRoutingID())); 715 Send(new ViewMsg_SwapOut(GetRoutingID()));
709 } else { 716 preserve_render_view_host = true;
710 // This RenderViewHost doesn't have a live renderer, so just skip the unload 717 timed_out = false;
711 // event.
712 OnSwappedOut(true);
713 } 718 }
719 OnSwappedOut(timed_out, preserve_render_view_host);
714 } 720 }
715 721
716 void RenderViewHostImpl::OnSwapOutACK() { 722 void RenderViewHostImpl::OnSwapOutACK() {
717 OnSwappedOut(false); 723 OnSwappedOut(false, false);
718 } 724 }
719 725
720 void RenderViewHostImpl::OnSwappedOut(bool timed_out) { 726 void RenderViewHostImpl::OnSwappedOut(bool timed_out,
721 // Stop the hang monitor now that the unload handler has finished. 727 bool preserve_render_view_host) {
722 decrement_in_flight_event_count(); 728
723 StopHangMonitorTimeout(); 729 should_be_preserved_on_swap_out_ = preserve_render_view_host;
724 is_waiting_for_unload_ack_ = false; 730 if (!preserve_render_view_host) {
725 has_timed_out_on_unload_ = timed_out; 731 // Stop the hang monitor now that the unload handler has finished.
732 decrement_in_flight_event_count();
733 StopHangMonitorTimeout();
734 is_waiting_for_unload_ack_ = false;
735 has_timed_out_on_unload_ = timed_out;
736 }
726 delegate_->SwappedOut(this); 737 delegate_->SwappedOut(this);
727 } 738 }
728 739
729 void RenderViewHostImpl::WasSwappedOut() { 740 void RenderViewHostImpl::WasSwappedOut() {
741 // Now that we're no longer the active RVH in the tab, start filtering out
742 // most IPC messages. Usually the renderer will have stopped sending
743 // messages as of OnSwapOutACK. However, we may have timed out waiting
744 // for that message, and additional IPC messages may keep streaming in.
745 // We filter them out, as long as that won't cause problems (e.g., we
746 // still allow synchronous messages through).
747 SetSwappedOut(true);
748
749 // The RenderView should not exit yet. It still has to execute the unload
Charlie Reis 2013/12/09 20:12:29 This doesn't make sense to me. The renderer won't
750 // event.
751 if (should_be_preserved_on_swap_out_) {
752 need_to_perform_clean_up_on_swapped_out_ = true;
753 return;
754 }
755 need_to_perform_clean_up_on_swapped_out_ = false;
pasko 2013/12/10 19:59:29 when is it the case that (should_be_preserved_on_s
756
730 // Don't bother reporting hung state anymore. 757 // Don't bother reporting hung state anymore.
731 StopHangMonitorTimeout(); 758 StopHangMonitorTimeout();
732 759
733 // If we have timed out on running the unload handler, we consider 760 // If we have timed out on running the unload handler, we consider
734 // the process hung and we should terminate it if there are no other tabs 761 // the process hung and we should terminate it if there are no other tabs
735 // using the process. If there are other views using this process, the 762 // using the process. If there are other views using this process, the
736 // unresponsive renderer timeout will catch it. 763 // unresponsive renderer timeout will catch it.
737 bool hung = has_timed_out_on_unload_; 764 bool hung = has_timed_out_on_unload_;
738 765
739 // Now that we're no longer the active RVH in the tab, start filtering out
740 // most IPC messages. Usually the renderer will have stopped sending
741 // messages as of OnSwapOutACK. However, we may have timed out waiting
742 // for that message, and additional IPC messages may keep streaming in.
743 // We filter them out, as long as that won't cause problems (e.g., we
744 // still allow synchronous messages through).
745 SetSwappedOut(true);
746
747 // If we are not running the renderer in process and no other tab is using 766 // If we are not running the renderer in process and no other tab is using
748 // the hung process, consider it eligible to be killed, assuming it is a real 767 // the hung process, consider it eligible to be killed, assuming it is a real
749 // process (unit tests don't have real processes). 768 // process (unit tests don't have real processes).
750 if (hung) { 769 if (hung) {
751 base::ProcessHandle process_handle = GetProcess()->GetHandle(); 770 base::ProcessHandle process_handle = GetProcess()->GetHandle();
752 int views = 0; 771 int views = 0;
753 772
754 // Count the number of active widget hosts for the process, which 773 // Count the number of active widget hosts for the process, which
755 // is equivalent to views using the process as of this writing. 774 // is equivalent to views using the process as of this writing.
756 scoped_ptr<RenderWidgetHostIterator> widgets( 775 scoped_ptr<RenderWidgetHostIterator> widgets(
(...skipping 1539 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 void RenderViewHostImpl::AttachToFrameTree() { 2315 void RenderViewHostImpl::AttachToFrameTree() {
2297 FrameTree* frame_tree = delegate_->GetFrameTree(); 2316 FrameTree* frame_tree = delegate_->GetFrameTree();
2298 2317
2299 frame_tree->SwapMainFrame(main_render_frame_host_.get()); 2318 frame_tree->SwapMainFrame(main_render_frame_host_.get());
2300 if (main_frame_id() != FrameTreeNode::kInvalidFrameId) { 2319 if (main_frame_id() != FrameTreeNode::kInvalidFrameId) {
2301 frame_tree->OnFirstNavigationAfterSwap(main_frame_id()); 2320 frame_tree->OnFirstNavigationAfterSwap(main_frame_id());
2302 } 2321 }
2303 } 2322 }
2304 2323
2305 } // namespace content 2324 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698