Changeset 241606 in webkit
- Timestamp:
- Feb 15, 2019 1:03:53 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r241604 r241606 1 2019-02-15 Chris Dumez <cdumez@apple.com> 2 3 Regression(PSON) Navigating quickly back and forth can lead to getting 'about:blank' in the backforward list 4 https://bugs.webkit.org/show_bug.cgi?id=194717 5 <rdar://problem/47884404> 6 7 Reviewed by Brady Eidson. 8 9 When the client does a history navigation, the UIProcess sends a WebPage::GoToBackForwardItem IPC to the 10 WebProcess and the WebProcess sends a WebPageProxy::BackForwardGoToItem IPC back to the UIProcess to 11 update the current item in the BackForwardList. This means that there is a slight delay between the 12 point a client requests a history navigation and the point where the BackForwardList's current item gets 13 update. This delay is pre-existing behavior and not new to PSON. 14 15 However, with PSON enabled, if we decide to process-swap for the history navigation, we'll tell the 16 previous (committed) process to ignore the load and we ask a new (provisional) process to do the history 17 navigation. When the previous process receives the request to ignore the history navigation, it restores 18 the History's current item to the one previous the navigation, which sends a WebPageProxy::GoToBackForwardItem 19 IPC to the UIProcess to update the BackForwardList as well. In parallel, the new process starts the 20 history navigation and also sends a WebPageProxy::GoToBackForwardItem to update the BackForwardList's 21 current item as well. We end up with a race between the 2 GoToBackForwardItem IPC messages coming from 22 the old and new process. If the old process's message loses the race, we end up with the wrong current 23 history item getting set in the UIProcess. Later, when we commit the provisional load and try to suspend 24 the previous page, we would save the SuspendedPage on the *wrong* BackForwardList item. If one tries to 25 load this BackForwardList item later, we'll use its SuspendedPage and try to unsuspend it. However, 26 because the PageCache entry is saved on another HistoryItem than the one getting loaded in the WebProcess 27 side, we attempt to do a regular load instead of a PageCache restore. We end up failing the load because 28 pages cannot trigger new loads while in page cache. Because the load fails, we end up loading the 29 initial empty document and this is how we end up with 'about:blank' in the back forward list. 30 31 To address the issue, update WebPageProxy::backForwardGoToItem() to ignore messages from the old/committed 32 WebProcess when there is a pending provisional load. If the committed processes starts a legit new 33 load, it would clear any existing pending provisional load before attempting the call backForwardGoToItem(). 34 As a result, ignoring such messages from the old processes when there is a pending provisional load is 35 safe. 36 37 In the future, we should probably move more of the history / backForwardList management to the UIProcess 38 to avoid this sort of issues. This would be a much larger refactoring though so I am going with this 39 simpler fix that is easily cherry-pickable for now. 40 41 * UIProcess/WebPageProxy.cpp: 42 (WebKit::WebPageProxy::suspendCurrentPageIfPossible): 43 (WebKit::WebPageProxy::continueNavigationInNewProcess): 44 (WebKit::WebPageProxy::backForwardGoToItem): 45 1 46 2019-02-15 Alex Christensen <achristensen@webkit.org> 2 47 -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r241556 r241606 246 246 247 247 #define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - WebPageProxy::" fmt, this, ##__VA_ARGS__) 248 #define RELEASE_LOG_ERROR_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_ERROR_IF(isAlwaysOnLoggingAllowed(), channel, "%p - WebPageProxy::" fmt, this, ##__VA_ARGS__) 248 249 249 250 // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively. … … 761 762 762 763 // If the client forced a swap then it may not be Web-compatible to suspend the previous page because other windows may have an opener link to the page. 763 if (processSwapRequestedByClient == ProcessSwapRequestedByClient::Yes) 764 if (processSwapRequestedByClient == ProcessSwapRequestedByClient::Yes) { 765 RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "suspendCurrentPageIfPossible: Not suspending current page for process pid %i because the swap was requested by the client", m_process->processIdentifier()); 764 766 return false; 765 766 if (isPageOpenedByDOMShowingInitialEmptyDocument()) 767 } 768 769 if (isPageOpenedByDOMShowingInitialEmptyDocument()) { 770 RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "suspendCurrentPageIfPossible: Not suspending current page for process pid %i because it is showing the initial empty document", m_process->processIdentifier()); 767 771 return false; 772 } 768 773 769 774 auto* fromItem = navigation.fromItem(); 770 775 if (!fromItem) { 771 LOG(ProcessSwapping, "WebPageProxy %" PRIu64 " unable to create suspended page for process pid %i - No current back/forward item", pageID(), m_process->processIdentifier());776 RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "suspendCurrentPageIfPossible: Not suspending current page for process pid %i because the navigation does not have a fromItem", m_process->processIdentifier()); 772 777 return false; 773 778 } … … 775 780 // If the source and the destination back / forward list items are the same, then this is a client-side redirect. In this case, 776 781 // there is no need to suspend the previous page as there will be no way to get back to it. 777 if (fromItem == m_backForwardList->currentItem()) 782 if (fromItem == m_backForwardList->currentItem()) { 783 RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "suspendCurrentPageIfPossible: Not suspending current page for process pid %i because this is a client-side redirect", m_process->processIdentifier()); 778 784 return false; 779 785 } 786 787 if (fromItem->url() != pageLoadState().url()) { 788 RELEASE_LOG_ERROR_IF_ALLOWED(ProcessSwapping, "suspendCurrentPageIfPossible: Not suspending current page for process pid %i because fromItem's URL does not match the page URL.", m_process->processIdentifier()); 789 ASSERT_NOT_REACHED(); 790 return false; 791 } 792 793 RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "suspendCurrentPageIfPossible: Suspending current page for process pid %i", m_process->processIdentifier()); 780 794 auto suspendedPage = std::make_unique<SuspendedPageProxy>(*this, m_process.copyRef(), *fromItem, *mainFrameID); 781 795 … … 2837 2851 2838 2852 if (m_provisionalPage) { 2853 RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "continueNavigationInNewProcess: There is already a pending provisional load, cancelling it (provisonalNavigationID: %llu, navigationID: %llu)", m_provisionalPage->navigationID(), navigation.navigationID()); 2839 2854 if (m_provisionalPage->navigationID() != navigation.navigationID()) 2840 2855 m_provisionalPage->cancel(); … … 5476 5491 void WebPageProxy::backForwardGoToItem(const BackForwardItemIdentifier& itemID, SandboxExtension::Handle& sandboxExtensionHandle) 5477 5492 { 5493 // On process swap, we tell the previous process to ignore the load, which causes it so restore its current back forward item to its previous 5494 // value. Since the load is really going on in a new provisional process, we want to ignore such requests from the committed process. 5495 // Any real new load in the committed process would have cleared m_provisionalPage. 5496 if (m_provisionalPage) 5497 return; 5498 5478 5499 backForwardGoToItemShared(m_process.copyRef(), itemID, sandboxExtensionHandle); 5479 5500 } -
trunk/Tools/ChangeLog
r241602 r241606 1 2019-02-15 Chris Dumez <cdumez@apple.com> 2 3 Regression(PSON) Navigating quickly back and forth can lead to getting 'about:blank' in the backforward list 4 https://bugs.webkit.org/show_bug.cgi?id=194717 5 <rdar://problem/47884404> 6 7 Reviewed by Brady Eidson. 8 9 Add API test coverage. 10 11 * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm: 12 1 13 2019-02-15 Youenn Fablet <youenn@apple.com> 2 14 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm
r241556 r241606 2024 2024 } 2025 2025 2026 static void runQuickBackForwardNavigationTest(ShouldEnablePSON shouldEnablePSON) 2027 { 2028 auto processPoolConfiguration = psonProcessPoolConfiguration(); 2029 processPoolConfiguration.get().processSwapsOnNavigation = shouldEnablePSON == ShouldEnablePSON::Yes ? YES : NO; 2030 auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]); 2031 2032 auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]); 2033 [webViewConfiguration setProcessPool:processPool.get()]; 2034 auto handler = adoptNS([[PSONScheme alloc] init]); 2035 [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"pson"]; 2036 2037 auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]); 2038 auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]); 2039 [webView setNavigationDelegate:delegate.get()]; 2040 2041 [webView configuration].preferences.safeBrowsingEnabled = NO; 2042 2043 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main1.html"]]; 2044 [webView loadRequest:request]; 2045 2046 TestWebKitAPI::Util::run(&done); 2047 done = false; 2048 2049 auto webkitPID = [webView _webProcessIdentifier]; 2050 2051 request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main2.html"]]; 2052 [webView loadRequest:request]; 2053 2054 TestWebKitAPI::Util::run(&done); 2055 done = false; 2056 2057 EXPECT_EQ(webkitPID, [webView _webProcessIdentifier]); 2058 2059 request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.apple.com/main.html"]]; 2060 [webView loadRequest:request]; 2061 2062 TestWebKitAPI::Util::run(&done); 2063 done = false; 2064 2065 auto applePID = [webView _webProcessIdentifier]; 2066 if (shouldEnablePSON == ShouldEnablePSON::Yes) 2067 EXPECT_NE(webkitPID, applePID); 2068 else 2069 EXPECT_EQ(webkitPID, applePID); 2070 2071 for (unsigned i = 0; i < 10; ++i) { 2072 [webView goBack]; 2073 TestWebKitAPI::Util::sleep(0.1); 2074 [webView goForward]; 2075 TestWebKitAPI::Util::spinRunLoop(0.1); 2076 } 2077 2078 Vector<String> backForwardListURLs; 2079 auto* backForwardList = [webView backForwardList]; 2080 for (unsigned i = 0; i < backForwardList.backList.count; ++i) 2081 backForwardListURLs.append([backForwardList.backList[i].URL absoluteString]); 2082 backForwardListURLs.append([backForwardList.currentItem.URL absoluteString]); 2083 for (unsigned i = 0; i < backForwardList.forwardList.count; ++i) 2084 backForwardListURLs.append([backForwardList.forwardList[i].URL absoluteString]); 2085 EXPECT_EQ(3u, backForwardListURLs.size()); 2086 EXPECT_WK_STREQ("pson://www.webkit.org/main1.html", backForwardListURLs[0]); 2087 EXPECT_WK_STREQ("pson://www.webkit.org/main2.html", backForwardListURLs[1]); 2088 EXPECT_WK_STREQ("pson://www.apple.com/main.html", backForwardListURLs[2]); 2089 } 2090 2091 TEST(ProcessSwap, QuickBackForwardNavigationWithoutPSON) 2092 { 2093 runQuickBackForwardNavigationTest(ShouldEnablePSON::No); 2094 } 2095 2096 TEST(ProcessSwap, QuickBackForwardNavigationWithPSON) 2097 { 2098 runQuickBackForwardNavigationTest(ShouldEnablePSON::Yes); 2099 } 2100 2026 2101 TEST(ProcessSwap, NavigationWithLockedHistoryWithoutPSON) 2027 2102 {
Note: See TracChangeset
for help on using the changeset viewer.