Index: content/renderer/render_frame_impl.cc |
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc |
index 4ae46edcbcfd761358664b569604c6c7a59dc2b6..eadb6fcefd26c357799a907f71ed60080dd42a11 100644 |
--- a/content/renderer/render_frame_impl.cc |
+++ b/content/renderer/render_frame_impl.cc |
@@ -1753,6 +1753,7 @@ void RenderFrameImpl::OnBeforeUnload(bool is_reload) { |
// Save the routing_id, as the RenderFrameImpl can be deleted in |
// dispatchBeforeUnloadEvent. See https://crbug.com/666714 for details. |
int routing_id = routing_id_; |
+ base::WeakPtr<RenderFrameImpl> weak_this = weak_factory_.GetWeakPtr(); |
base::TimeTicks before_unload_start_time = base::TimeTicks::Now(); |
@@ -1761,6 +1762,15 @@ void RenderFrameImpl::OnBeforeUnload(bool is_reload) { |
// execute the BeforeUnload event in this frame and local child frames. It |
// should also be dispatched to out-of-process child frames. |
bool proceed = frame_->DispatchBeforeUnloadEvent(is_reload); |
+ if (IsBrowserSideNavigationEnabled() && proceed && weak_this) { |
+ ran_before_unload_ = true; |
+ // If there's already a pending navigation its didcommitprovisionalload or |
+ // didstoploading IPCs (exact one which fires is racy) would interfere with |
+ // the new navigation. By forcing the old navigation to be cancelled first, |
+ // then we are assured that the IPC pipe is flushed of IPCs related to a |
+ // previous navigation. |
+ frame_->StopLoading(); |
jam
2017/07/08 01:32:49
this prevents stray FrameHostMsg_DidCommitProvisio
clamy
2017/07/10 13:02:05
That seems wrong to me. If we're trying to load a
|
+ } |
base::TimeTicks before_unload_end_time = base::TimeTicks::Now(); |
RenderThread::Get()->Send(new FrameHostMsg_BeforeUnload_ACK( |
@@ -5073,6 +5083,13 @@ void RenderFrameImpl::DidStopLoading() { |
SendUpdateFaviconURL(icon_types_mask); |
render_view_->FrameDidStopLoading(frame_); |
+ |
+ if (IsBrowserSideNavigationEnabled() && ran_before_unload_) { |
+ // Avoid a previous navigation's didstop IPC from resetting the |
+ // NavigationHandle of the next navigation. |
+ return; |
jam
2017/07/08 01:32:49
this prevents the other case of stray FrameHostMsg
|
+ } |
+ |
Send(new FrameHostMsg_DidStopLoading(routing_id_)); |
} |
@@ -5163,6 +5180,7 @@ void RenderFrameImpl::OnCommitNavigation( |
: nullptr); |
browser_side_navigation_pending_ = false; |
+ ran_before_unload_ = false; |
NavigateInternal(common_params, StartNavigationParams(), request_params, |
std::move(stream_override)); |
@@ -5194,6 +5212,7 @@ void RenderFrameImpl::OnFailedNavigation( |
pending_navigation_params_.reset(new NavigationParams( |
common_params, StartNavigationParams(), request_params)); |
+ ran_before_unload_ = false; |
// Send the provisional load failure. |
blink::WebURLError error = |