Changeset 244493 in webkit
- Timestamp:
- Apr 21, 2019 1:14:04 PM (5 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r244484 r244493 1 2019-04-21 Chris Dumez <cdumez@apple.com> 2 3 Regression(r243767) WebFrame::m_navigationIsContinuingInAnotherProcess flag is never reset 4 https://bugs.webkit.org/show_bug.cgi?id=197144 5 6 Reviewed by Darin Adler. 7 8 WebFrame::m_navigationIsContinuingInAnotherProcess flag is never reset since it was introduced in 9 r243767. This leads to leaking Navigation objects in the UIProcess when reusing a previously 10 suspended process because such process will no longer send the DidDestroyNavigation IPC. 11 12 It turns out that resetting the flags causes API tests such as ProcessSwap.QuickBackForwardNavigationWithPSON 13 to ASSERT. This is because when the UIProcess quickly navigate back and forth without waiting for policy 14 decisions, we may end up getting the policy decision for a particular navigation *after* we've sent the 15 DidDestroyNavigation. 16 17 As a result, this patch reverts r243767 and fixes in the assertion in http/tests/adClickAttribution/store-ad-click-attribution.html 18 another way. We initially assumed that the logic in WebPageProxy::didDestroyNavigation() was failing to 19 ignore the DidDestroyNavigation from the previous process after a swap due to a race, maybe because it was 20 sometimes received too late and m_provisionalPage was already cleared. However, this would not make sense 21 since the test is crashing consistently and the page would no longer be able to receive IPC from the 22 previous process *after* we've committed the provisional process/page. 23 24 The real issue was that the DidDestroyNavigation IPC was received *before* we could construct the 25 provisional page, which is why the logic in WebPageProxy::didDestroyNavigation() was failing to ignore 26 the bad IPC. In WebPageProxy::receivedNavigationPolicyDecision(), we were calling receivedPolicyDecision() 27 (which would send the DidReceivePolicyDecision to the previous WebProcess) and then continueNavigationInNewProcess() 28 in order to construct the provisional page. I personally did not expect we could receive IPC between the 29 calls to receivedNavigationPolicyDecision() and receivedPolicyDecision(), since we are not yielding and since 30 the DidReceivePolicyDecision IPC is asynchronous. However, this is exactly what was happening in the context 31 of this test. The reason is that the DidReceivePolicyDecision IPC was getting wrapped in a synchronous message 32 and sent as synchronous message due to the Connection::m_inDispatchMessageMarkedToUseFullySynchronousModeForTesting 33 flag which seems to get set in the test due to some EventSender IPC. I believe this is because the test uses 34 EventSender to do a click on a link which triggers the navigation. 35 36 To address the issue, I now call receivedNavigationPolicyDecision() *after* continueNavigationInNewProcess() 37 to make sure that we always start the provisional load in the new process before we tell the previous process 38 to stop loading. This way, there is no way we get IPC from the previous process about the current navigation 39 before we have a provisional page. 40 41 * UIProcess/WebPageProxy.cpp: 42 (WebKit::WebPageProxy::receivedNavigationPolicyDecision): 43 (WebKit::WebPageProxy::didDestroyNavigation): 44 * WebProcess/WebPage/WebFrame.cpp: 45 (WebKit::WebFrame::didReceivePolicyDecision): 46 (WebKit::WebFrame::documentLoaderDetached): 47 * WebProcess/WebPage/WebFrame.h: 48 1 49 2019-04-20 Chris Dumez <cdumez@apple.com> 2 50 -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r244464 r244493 2790 2790 RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "decidePolicyForNavigationAction: keep using process %i for navigation, reason: %{public}s", processIdentifier(), reason.utf8().data()); 2791 2791 2792 if (shouldProcessSwap) { 2793 // FIXME: Architecturally we do not currently support multiple WebPage's with the same ID in a given WebProcess. 2794 // In the case where the destination WebProcess has a SuspendedPageProxy for this WebPage, we should have thrown 2795 // it away to support WebProcess re-use. 2796 ASSERT(destinationSuspendedPage || !process().processPool().hasSuspendedPageFor(processForNavigation, *this)); 2797 2798 auto suspendedPage = destinationSuspendedPage ? process().processPool().takeSuspendedPage(*destinationSuspendedPage) : nullptr; 2799 if (suspendedPage && suspendedPage->failedToSuspend()) 2800 suspendedPage = nullptr; 2801 2802 continueNavigationInNewProcess(navigation, WTFMove(suspendedPage), WTFMove(processForNavigation), processSwapRequestedByClient, WTFMove(data)); 2803 } 2804 2792 2805 receivedPolicyDecision(policyAction, navigation.ptr(), shouldProcessSwap ? WTF::nullopt : WTFMove(data), WTFMove(sender), shouldProcessSwap ? WillContinueLoadInNewProcess::Yes : WillContinueLoadInNewProcess::No); 2793 2794 if (!shouldProcessSwap)2795 return;2796 2797 // FIXME: Architecturally we do not currently support multiple WebPage's with the same ID in a given WebProcess.2798 // In the case where the destination WebProcess has a SuspendedPageProxy for this WebPage, we should have thrown2799 // it away to support WebProcess re-use.2800 ASSERT(destinationSuspendedPage || !process().processPool().hasSuspendedPageFor(processForNavigation, *this));2801 2802 auto suspendedPage = destinationSuspendedPage ? process().processPool().takeSuspendedPage(*destinationSuspendedPage) : nullptr;2803 if (suspendedPage && suspendedPage->failedToSuspend())2804 suspendedPage = nullptr;2805 2806 continueNavigationInNewProcess(navigation, WTFMove(suspendedPage), WTFMove(processForNavigation), processSwapRequestedByClient, WTFMove(data));2807 2806 }); 2808 2807 } … … 3868 3867 { 3869 3868 PageClientProtector protector(pageClient()); 3869 3870 // On process-swap, the previous process tries to destroy the navigation but the provisional process is actually taking over the navigation. 3871 if (m_provisionalPage && m_provisionalPage->navigationID() == navigationID) 3872 return; 3870 3873 3871 3874 // FIXME: Message check the navigationID. -
trunk/Source/WebKit/WebProcess/WebPage/WebFrame.cpp
r243767 r244493 279 279 } 280 280 281 if (action == PolicyAction::StopAllLoads)282 m_navigationIsContinuingInAnotherProcess = true;283 284 281 function(action, identifier); 285 282 } … … 816 813 void WebFrame::documentLoaderDetached(uint64_t navigationID) 817 814 { 818 if (m_navigationIsContinuingInAnotherProcess)819 return;820 815 if (auto* page = this->page()) 821 816 page->send(Messages::WebPageProxy::DidDestroyNavigation(navigationID)); -
trunk/Source/WebKit/WebProcess/WebPage/WebFrame.h
r243767 r244493 189 189 190 190 uint64_t m_frameID { 0 }; 191 bool m_navigationIsContinuingInAnotherProcess { false };192 191 193 192 #if PLATFORM(IOS_FAMILY)
Note: See TracChangeset
for help on using the changeset viewer.