Title: [245904] trunk
Revision
245904
Author
[email protected]
Date
2019-05-30 14:00:57 -0700 (Thu, 30 May 2019)

Log Message

Stop StorageManager when network process is ready to suspend
https://bugs.webkit.org/show_bug.cgi?id=198201
<rdar://problem/49683172>

Reviewed by Youenn Fablet.

Source/WebKit:

To avoid local storage database operations that can hold lock to database files, suspend thread of
StorageManager when network process is about to suspend.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::actualPrepareToSuspend):
(WebKit::NetworkProcess::resume):
* NetworkProcess/NetworkSession.cpp:
(WebKit::NetworkSession::~NetworkSession):
* NetworkProcess/WebStorage/StorageManager.cpp:
(WebKit::StorageManager::suspend):
(WebKit::StorageManager::resume):
* NetworkProcess/WebStorage/StorageManager.h:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm:
(TEST):
* TestWebKitAPI/Tests/WebKitCocoa/local-storage-process-suspends-1.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/local-storage-process-suspends-2.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (245903 => 245904)


--- trunk/Source/WebKit/ChangeLog	2019-05-30 20:34:12 UTC (rev 245903)
+++ trunk/Source/WebKit/ChangeLog	2019-05-30 21:00:57 UTC (rev 245904)
@@ -1,3 +1,24 @@
+2019-05-30  Sihui Liu  <[email protected]>
+
+        Stop StorageManager when network process is ready to suspend
+        https://bugs.webkit.org/show_bug.cgi?id=198201
+        <rdar://problem/49683172>
+
+        Reviewed by Youenn Fablet.
+
+        To avoid local storage database operations that can hold lock to database files, suspend thread of
+        StorageManager when network process is about to suspend.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::actualPrepareToSuspend):
+        (WebKit::NetworkProcess::resume):
+        * NetworkProcess/NetworkSession.cpp:
+        (WebKit::NetworkSession::~NetworkSession):
+        * NetworkProcess/WebStorage/StorageManager.cpp:
+        (WebKit::StorageManager::suspend):
+        (WebKit::StorageManager::resume):
+        * NetworkProcess/WebStorage/StorageManager.h:
+
 2019-05-30  Wenson Hsieh  <[email protected]>
 
         Missing caret when focusing an editable field if the selection was set when WKWebView wasn't first responder

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (245903 => 245904)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2019-05-30 20:34:12 UTC (rev 245903)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2019-05-30 21:00:57 UTC (rev 245904)
@@ -2038,6 +2038,9 @@
     for (auto& server : m_swServers.values())
         server->startSuspension([delayedTaskCounter] { });
 #endif
+
+    for (auto& session : m_networkSessions)
+        session.value->storageManager().suspend([delayedTaskCounter] { });
 }
 
 void NetworkProcess::processWillSuspendImminently()
@@ -2106,6 +2109,9 @@
     for (auto& server : m_idbServers.values())
         server->resume();
 #endif
+
+    for (auto& session : m_networkSessions)
+        session.value->storageManager().resume();
 }
 
 void NetworkProcess::prefetchDNS(const String& hostname)

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp (245903 => 245904)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2019-05-30 20:34:12 UTC (rev 245903)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2019-05-30 21:00:57 UTC (rev 245904)
@@ -90,6 +90,7 @@
 
 NetworkSession::~NetworkSession()
 {
+    m_storageManager->resume();
     m_storageManager->waitUntilWritesFinished();
 }
 

Modified: trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp (245903 => 245904)


--- trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp	2019-05-30 20:34:12 UTC (rev 245903)
+++ trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp	2019-05-30 21:00:57 UTC (rev 245904)
@@ -944,6 +944,43 @@
     semaphore.wait();
 }
 
+void StorageManager::suspend(CompletionHandler<void()>&& completionHandler)
+{
+    if (m_isEphemeral)
+        return;
+
+    Locker<Lock> stateLocker(m_stateLock);
+    if (m_state != State::Running)
+        return;
+    m_state = State::WillSuspend;
+
+    m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] () mutable {
+        Locker<Lock> stateLocker(m_stateLock);
+        ASSERT(m_state != State::Suspended);
+
+        completionHandler();
+
+        if (m_state != State::WillSuspend)
+            return;
+        m_state = State::Suspended;
+        while (m_state == State::Suspended)
+            m_stateChangeCondition.wait(m_stateLock);
+        ASSERT(m_state == State::Running);
+    });
+}
+
+void StorageManager::resume()
+{
+    if (m_isEphemeral)
+        return;
+
+    Locker<Lock> stateLocker(m_stateLock);
+    auto previousState = m_state;
+    m_state = State::Running;
+    if (previousState == State::Suspended)
+        m_stateChangeCondition.notifyOne();
+}
+
 StorageManager::StorageArea* StorageManager::findStorageArea(IPC::Connection& connection, uint64_t storageMapID) const
 {
     std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connection.uniqueID(), storageMapID);

Modified: trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h (245903 => 245904)


--- trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h	2019-05-30 20:34:12 UTC (rev 245903)
+++ trunk/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h	2019-05-30 21:00:57 UTC (rev 245904)
@@ -58,6 +58,8 @@
 
     void processDidCloseConnection(IPC::Connection&);
     void waitUntilWritesFinished();
+    void suspend(CompletionHandler<void()>&&);
+    void resume();
 
     void getSessionStorageOrigins(Function<void(HashSet<WebCore::SecurityOriginData>&&)>&& completionHandler);
     void deleteSessionStorageOrigins(Function<void()>&& completionHandler);
@@ -113,6 +115,15 @@
 
     HashMap<WebCore::SecurityOriginData, Ref<WebCore::StorageMap>> m_ephemeralStorage;
     bool m_isEphemeral { false };
+
+    enum class State {
+        Running,
+        WillSuspend,
+        Suspended
+    };
+    State m_state;
+    Lock m_stateLock;
+    Condition m_stateChangeCondition;
 };
 
 } // namespace WebKit

Modified: trunk/Tools/ChangeLog (245903 => 245904)


--- trunk/Tools/ChangeLog	2019-05-30 20:34:12 UTC (rev 245903)
+++ trunk/Tools/ChangeLog	2019-05-30 21:00:57 UTC (rev 245904)
@@ -1,3 +1,17 @@
+2019-05-30  Sihui Liu  <[email protected]>
+
+        Stop StorageManager when network process is ready to suspend
+        https://bugs.webkit.org/show_bug.cgi?id=198201
+        <rdar://problem/49683172>
+
+        Reviewed by Youenn Fablet.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm:
+        (TEST):
+        * TestWebKitAPI/Tests/WebKitCocoa/local-storage-process-suspends-1.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/local-storage-process-suspends-2.html: Added.
+
 2019-05-30  David Quesada  <[email protected]>
 
         REGRESSION (r245756) [Mac] 2 TestWebKitAPI.DownloadProgress* and TestWebKitAPI._WKDownload.DownloadMonitorCancel are flaky timeouts

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (245903 => 245904)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2019-05-30 20:34:12 UTC (rev 245903)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2019-05-30 21:00:57 UTC (rev 245904)
@@ -650,6 +650,8 @@
 		935786CE20F6A2A10000CDFC /* IndexedDB.sqlite3-shm in Copy Resources */ = {isa = PBXBuildFile; fileRef = 934FA5C620F69FED0040DC1B /* IndexedDB.sqlite3-shm */; };
 		9361002914DC95A70061379D /* lots-of-iframes.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9361002814DC957B0061379D /* lots-of-iframes.html */; };
 		93625D271CD9741C006DC1F1 /* large-video-without-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93625D261CD973AF006DC1F1 /* large-video-without-audio.html */; };
+		9368A25E229EFB4700A829CA /* local-storage-process-suspends-1.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9368A25D229EFB3A00A829CA /* local-storage-process-suspends-1.html */; };
+		9368A25F229EFB4700A829CA /* local-storage-process-suspends-2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9368A25C229EFB3A00A829CA /* local-storage-process-suspends-2.html */; };
 		936F72801CD7D9EC0068A0FB /* large-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 936F727E1CD7D9D00068A0FB /* large-video-with-audio.html */; };
 		936F72811CD7D9EC0068A0FB /* large-video-with-audio.mp4 in Copy Resources */ = {isa = PBXBuildFile; fileRef = 936F727F1CD7D9D00068A0FB /* large-video-with-audio.mp4 */; };
 		93AF4ECE1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AF4ECD1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp */; };
@@ -1231,6 +1233,8 @@
 				573255A722139BC700396AE8 /* load-web-archive-2.html in Copy Resources */,
 				57901FB11CAF142D00ED64F9 /* LoadInvalidURLRequest.html in Copy Resources */,
 				CA7787FF228CEFDB00E50463 /* local-storage-process-crashes.html in Copy Resources */,
+				9368A25E229EFB4700A829CA /* local-storage-process-suspends-1.html in Copy Resources */,
+				9368A25F229EFB4700A829CA /* local-storage-process-suspends-2.html in Copy Resources */,
 				8C10AF98206467920018FD90 /* localstorage-empty-string-value.html in Copy Resources */,
 				51E6A8961D2F1CA700C004B6 /* LocalStorageClear.html in Copy Resources */,
 				46C519E61D3563FD00DAA51A /* LocalStorageNullEntries.html in Copy Resources */,
@@ -1911,6 +1915,8 @@
 		93575C551D30366E000D604D /* focus-inputs.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "focus-inputs.html"; sourceTree = "<group>"; };
 		9361002814DC957B0061379D /* lots-of-iframes.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "lots-of-iframes.html"; sourceTree = "<group>"; };
 		93625D261CD973AF006DC1F1 /* large-video-without-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-without-audio.html"; sourceTree = "<group>"; };
+		9368A25C229EFB3A00A829CA /* local-storage-process-suspends-2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "local-storage-process-suspends-2.html"; sourceTree = "<group>"; };
+		9368A25D229EFB3A00A829CA /* local-storage-process-suspends-1.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "local-storage-process-suspends-1.html"; sourceTree = "<group>"; };
 		936F727E1CD7D9D00068A0FB /* large-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-with-audio.html"; sourceTree = "<group>"; };
 		936F727F1CD7D9D00068A0FB /* large-video-with-audio.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "large-video-with-audio.mp4"; sourceTree = "<group>"; };
 		939BA91614103412001A01BD /* DeviceScaleFactorOnBack.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DeviceScaleFactorOnBack.mm; sourceTree = "<group>"; };
@@ -3058,6 +3064,8 @@
 				F41AB99D1EF4692C0083FA08 /* link-and-target-div.html */,
 				F46128D1211E2D2500D9FADB /* link-in-iframe-and-input.html */,
 				CA7787FE228CEFC700E50463 /* local-storage-process-crashes.html */,
+				9368A25D229EFB3A00A829CA /* local-storage-process-suspends-1.html */,
+				9368A25C229EFB3A00A829CA /* local-storage-process-suspends-2.html */,
 				8C10AF97206467830018FD90 /* localstorage-empty-string-value.html */,
 				51E6A8951D2F1C7700C004B6 /* LocalStorageClear.html */,
 				46C519E21D35629600DAA51A /* LocalStorageNullEntries.html */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm (245903 => 245904)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm	2019-05-30 20:34:12 UTC (rev 245903)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm	2019-05-30 21:00:57 UTC (rev 245904)
@@ -98,6 +98,58 @@
     TestWebKitAPI::Util::run(&readyToContinue);
 }
 
+TEST(WKWebView, LocalStorageProcessSuspends)
+{
+    readyToContinue = false;
+    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+        readyToContinue = true;
+    }];
+    TestWebKitAPI::Util::run(&readyToContinue);
+
+    RetainPtr<LocalStorageMessageHandler> handler = adoptNS([[LocalStorageMessageHandler alloc] init]);
+    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
+    RetainPtr<WKProcessPool> processPool = adoptNS([[WKProcessPool alloc] init]);
+    [configuration setProcessPool:processPool.get()];
+
+    RetainPtr<WKWebView> webView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"local-storage-process-suspends-1" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView1 loadRequest:request];
+
+    receivedScriptMessage = false;
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    EXPECT_WK_STREQ(@"value", [lastScriptMessage body]);
+    
+    RetainPtr<WKWebView> webView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"local-storage-process-suspends-2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView2 loadRequest:request];
+
+    receivedScriptMessage = false;
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    EXPECT_WK_STREQ(@"value", [lastScriptMessage body]);
+
+    [processPool.get() _sendNetworkProcessWillSuspendImminently];
+
+    readyToContinue = false;
+    [webView1 evaluateJavaScript:@"window.localStorage.setItem('key', 'newValue')" completionHandler:^(id, NSError *) {
+        readyToContinue = true;
+    }];
+    TestWebKitAPI::Util::run(&readyToContinue);
+    
+    readyToContinue = false;
+    [webView2 evaluateJavaScript:@"window.localStorage.getItem('key')" completionHandler:^(id result, NSError *) {
+        EXPECT_TRUE([@"value" isEqualToString:result]);
+        readyToContinue = true;
+    }];
+    TestWebKitAPI::Util::run(&readyToContinue);
+    
+    [processPool.get() _sendNetworkProcessDidResume];
+
+    receivedScriptMessage = false;
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    EXPECT_WK_STREQ(@"newValue", [lastScriptMessage body]);
+}
+
 TEST(WKWebView, LocalStorageEmptyString)
 {
     readyToContinue = false;

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/local-storage-process-suspends-1.html (0 => 245904)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/local-storage-process-suspends-1.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/local-storage-process-suspends-1.html	2019-05-30 21:00:57 UTC (rev 245904)
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<script>
+
+localStorage.setItem('key', 'value');
+window.webkit.messageHandlers.testHandler.postMessage(localStorage.getItem('key'));
+
+</script>
\ No newline at end of file

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/local-storage-process-suspends-2.html (0 => 245904)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/local-storage-process-suspends-2.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/local-storage-process-suspends-2.html	2019-05-30 21:00:57 UTC (rev 245904)
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<script>
+
+var startValue = window.localStorage.getItem('key');
+window.webkit.messageHandlers.testHandler.postMessage(startValue);
+
+var tries = 10;
+var intervalID = setInterval(()=> {
+    var newValue = window.localStorage.getItem('key');
+    if (newValue != startValue || tries == 0) {
+        window.webkit.messageHandlers.testHandler.postMessage(newValue);
+        clearInterval(intervalID);
+    }
+    --tries;
+}, 100);
+
+</script>
\ No newline at end of file
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to