Don't kill the UIProcess until all local storage transactions have been committed.
authorroger_fong@apple.com <roger_fong@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jun 2014 19:23:24 +0000 (19:23 +0000)
committerroger_fong@apple.com <roger_fong@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jun 2014 19:23:24 +0000 (19:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134042.
<rdar://problem/16660724>.

Reviewed by Anders Carlsson.

* UIProcess/API/mac/WKView.mm: Add a listener for the application will terminate notification.
(-[WKView _applicationWillTerminate:]):
(-[WKView initWithFrame:context:configuration:webView:]):
* UIProcess/WebContext.cpp: Calls code in StorageManager to cleanup local storage transactions upon application termination.
(WebKit::WebContext::applicationWillTerminate):
* UIProcess/WebContext.h:

* UIProcess/Storage/StorageManager.cpp:
(WebKit::StorageManager::applicationWillTerminate):
Dispatch local storage cleanup task to background thread and make sure the UIProcess can't exit early.
* UIProcess/Storage/StorageManager.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@170156 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/mac/WKView.mm
Source/WebKit2/UIProcess/Storage/StorageManager.cpp
Source/WebKit2/UIProcess/Storage/StorageManager.h
Source/WebKit2/UIProcess/WebContext.cpp
Source/WebKit2/UIProcess/WebContext.h

index 013ba1d..11e1301 100644 (file)
@@ -1,3 +1,23 @@
+2014-06-18  Roger Fong  <roger_fong@apple.com>
+
+        Don't kill the UIProcess until all local storage transactions have been committed.
+        https://bugs.webkit.org/show_bug.cgi?id=134042.
+        <rdar://problem/16660724>.
+
+        Reviewed by Anders Carlsson.
+
+        * UIProcess/API/mac/WKView.mm: Add a listener for the application will terminate notification.
+        (-[WKView _applicationWillTerminate:]):
+        (-[WKView initWithFrame:context:configuration:webView:]):
+        * UIProcess/WebContext.cpp: Calls code in StorageManager to cleanup local storage transactions upon application termination.
+        (WebKit::WebContext::applicationWillTerminate):
+        * UIProcess/WebContext.h:
+
+        * UIProcess/Storage/StorageManager.cpp:
+        (WebKit::StorageManager::applicationWillTerminate):
+        Dispatch local storage cleanup task to background thread and make sure the UIProcess can't exit early.
+        * UIProcess/Storage/StorageManager.h:
+
 2014-06-19  Oliver Hunt  <oliver@apple.com>
 
         Switch to using the process parameters during initialisation
index eeb5c3e..adda843 100644 (file)
@@ -2622,6 +2622,11 @@ static void createSandboxExtensionsForFileUpload(NSPasteboard *pasteboard, Sandb
     _data->_page->viewStateDidChange(ViewState::IsVisible);
 }
 
+- (void)_applicationWillTerminate:(NSNotification *)notification
+{
+    _data->_page->process().context().applicationWillTerminate();
+}
+
 - (void)_accessibilityRegisterUIProcessTokens
 {
     // Initialize remote accessibility when the window connection has been established.
@@ -3485,6 +3490,8 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path)
     NSNotificationCenter* workspaceNotificationCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
     [workspaceNotificationCenter addObserver:self selector:@selector(_activeSpaceDidChange:) name:NSWorkspaceActiveSpaceDidChangeNotification object:nil];
 
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationWillTerminate:) name:NSApplicationWillTerminateNotification object:NSApp];
+
     return self;
 }
 
index cf6f53b..81c0196 100644 (file)
@@ -38,6 +38,7 @@
 #include <WebCore/StorageMap.h>
 #include <WebCore/TextEncoding.h>
 #include <memory>
+#include <wtf/threads/BinarySemaphore.h>
 
 using namespace WebCore;
 
@@ -588,6 +589,24 @@ void StorageManager::cloneSessionStorageNamespaceInternal(uint64_t storageNamesp
     sessionStorageNamespace->cloneTo(*newSessionStorageNamespace);
 }
 
+void StorageManager::applicationWillTerminate()
+{
+    BinarySemaphore semaphore;
+    m_queue->dispatch([this, &semaphore] {
+        Vector<std::pair<RefPtr<IPC::Connection>, uint64_t>> connectionAndStorageMapIDPairsToRemove;
+        for (auto& connectionStorageAreaPair : m_storageAreasByConnection) {
+            connectionStorageAreaPair.value->removeListener(connectionStorageAreaPair.key.first.get(), connectionStorageAreaPair.key.second);
+            connectionAndStorageMapIDPairsToRemove.append(connectionStorageAreaPair.key);
+        }
+
+        for (auto& connectionStorageAreaPair : connectionAndStorageMapIDPairsToRemove)
+            m_storageAreasByConnection.remove(connectionStorageAreaPair);
+
+        semaphore.signal();
+    });
+    semaphore.wait(std::numeric_limits<double>::max());
+}
+
 void StorageManager::invalidateConnectionInternal(IPC::Connection* connection)
 {
     Vector<std::pair<RefPtr<IPC::Connection>, uint64_t>> connectionAndStorageMapIDPairsToRemove;
index 56f4b6e..569c3c6 100644 (file)
@@ -57,6 +57,7 @@ public:
 
     void processWillOpenConnection(WebProcessProxy*);
     void processWillCloseConnection(WebProcessProxy*);
+    void applicationWillTerminate();
 
     // FIXME: Instead of a context + C function, this should take a WTF::Function, but we currently don't
     // support arguments in functions.
index eb2cf0d..2694f65 100644 (file)
@@ -720,6 +720,11 @@ void WebContext::processWillCloseConnection(WebProcessProxy* process)
     m_storageManager->processWillCloseConnection(process);
 }
 
+void WebContext::applicationWillTerminate()
+{
+    m_storageManager->applicationWillTerminate();
+}
+
 void WebContext::processDidFinishLaunching(WebProcessProxy* process)
 {
     ASSERT(m_processes.contains(process));
index 33021f5..69e9655 100644 (file)
@@ -165,6 +165,7 @@ public:
     void processWillCloseConnection(WebProcessProxy*);
     void processDidFinishLaunching(WebProcessProxy*);
 
+    void applicationWillTerminate();
     // Disconnect the process from the context.
     void disconnectProcess(WebProcessProxy*);