Title: [171704] trunk/Source/WebKit2
Revision
171704
Author
jp...@apple.com
Date
2014-07-28 15:26:52 -0700 (Mon, 28 Jul 2014)

Log Message

IDB transactions never reset if the Web Process ends before cleaning up
https://bugs.webkit.org/show_bug.cgi?id=135218

Reviewed by Darin Adler.

* DatabaseProcess/DatabaseToWebProcessConnection.cpp:
(WebKit::DatabaseToWebProcessConnection::didClose):
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
(WebKit::UniqueIDBDatabase::unregisterConnection):
(WebKit::UniqueIDBDatabase::didCompleteTransactionOperation):
(WebKit::UniqueIDBDatabase::openBackingStoreTransaction):
(WebKit::UniqueIDBDatabase::resetBackingStoreTransaction):
(WebKit::UniqueIDBDatabase::didEstablishTransaction):
(WebKit::UniqueIDBDatabase::didResetTransaction):
(WebKit::UniqueIDBDatabase::resetAllTransactions):
(WebKit::UniqueIDBDatabase::finalizeRollback):
(WebKit::UniqueIDBDatabase::absoluteDatabaseDirectory):
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::rollbackTransaction):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (171703 => 171704)


--- trunk/Source/WebKit2/ChangeLog	2014-07-28 22:19:11 UTC (rev 171703)
+++ trunk/Source/WebKit2/ChangeLog	2014-07-28 22:26:52 UTC (rev 171704)
@@ -1,3 +1,26 @@
+2014-07-25  Jeffrey Pfau  <jp...@apple.com>
+
+        IDB transactions never reset if the Web Process ends before cleaning up
+        https://bugs.webkit.org/show_bug.cgi?id=135218
+
+        Reviewed by Darin Adler.
+
+        * DatabaseProcess/DatabaseToWebProcessConnection.cpp:
+        (WebKit::DatabaseToWebProcessConnection::didClose):
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
+        (WebKit::UniqueIDBDatabase::unregisterConnection):
+        (WebKit::UniqueIDBDatabase::didCompleteTransactionOperation):
+        (WebKit::UniqueIDBDatabase::openBackingStoreTransaction):
+        (WebKit::UniqueIDBDatabase::resetBackingStoreTransaction):
+        (WebKit::UniqueIDBDatabase::didEstablishTransaction):
+        (WebKit::UniqueIDBDatabase::didResetTransaction):
+        (WebKit::UniqueIDBDatabase::resetAllTransactions):
+        (WebKit::UniqueIDBDatabase::finalizeRollback):
+        (WebKit::UniqueIDBDatabase::absoluteDatabaseDirectory):
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::rollbackTransaction):
+
 2014-07-27  Yusuke Suzuki  <utatane....@gmail.com>
 
         [GTK] Keep non-DATABASE_PROCESS build

Modified: trunk/Source/WebKit2/DatabaseProcess/DatabaseToWebProcessConnection.cpp (171703 => 171704)


--- trunk/Source/WebKit2/DatabaseProcess/DatabaseToWebProcessConnection.cpp	2014-07-28 22:19:11 UTC (rev 171703)
+++ trunk/Source/WebKit2/DatabaseProcess/DatabaseToWebProcessConnection.cpp	2014-07-28 22:26:52 UTC (rev 171704)
@@ -71,7 +71,9 @@
 
 void DatabaseToWebProcessConnection::didClose(IPC::Connection*)
 {
-
+    // The WebProcess has disconnected, close all of the connections associated with it
+    while (!m_idbConnections.isEmpty())
+        removeDatabaseProcessIDBConnection(m_idbConnections.begin()->key);
 }
 
 void DatabaseToWebProcessConnection::didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference messageReceiverName, IPC::StringReference messageName)

Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp (171703 => 171704)


--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp	2014-07-28 22:19:11 UTC (rev 171703)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp	2014-07-28 22:26:52 UTC (rev 171704)
@@ -113,9 +113,10 @@
 void UniqueIDBDatabase::unregisterConnection(DatabaseProcessIDBConnection& connection)
 {
     ASSERT(m_connections.contains(&connection));
+    resetAllTransactions(connection);
     m_connections.remove(&connection);
 
-    if (m_connections.isEmpty()) {
+    if (m_connections.isEmpty() && m_pendingTransactionRollbacks.isEmpty()) {
         shutdown(UniqueIDBDatabaseShutdownType::NormalShutdown);
         DatabaseProcess::shared().removeUniqueIDBDatabase(*this);
     }
@@ -337,10 +338,12 @@
     ASSERT(RunLoop::isMain());
 
     RefPtr<AsyncRequest> request = m_pendingTransactionRequests.take(transactionIdentifier);
-    if (!request)
-        return;
 
-    request->completeRequest(success);
+    if (request)
+        request->completeRequest(success);
+
+    if (m_pendingTransactionRollbacks.contains(transactionIdentifier))
+        finalizeRollback(transactionIdentifier);
 }
 
 void UniqueIDBDatabase::changeDatabaseVersion(const IDBIdentifier& transactionIdentifier, uint64_t newVersion, std::function<void(bool)> successCallback)
@@ -714,6 +717,7 @@
 
     bool success = m_backingStore->establishTransaction(transactionIdentifier, objectStoreIDs, mode);
 
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didEstablishTransaction, transactionIdentifier, success));
     postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didCompleteTransactionOperation, transactionIdentifier, success));
 }
 
@@ -744,6 +748,7 @@
 
     bool success = m_backingStore->resetTransaction(transactionIdentifier);
 
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didResetTransaction, transactionIdentifier, success));
     postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didCompleteTransactionOperation, transactionIdentifier, success));
 }
 
@@ -1070,6 +1075,62 @@
     request->completeRequest(errorCode, errorMessage);
 }
 
+void UniqueIDBDatabase::didEstablishTransaction(const IDBIdentifier& transactionIdentifier, bool success)
+{
+    ASSERT(RunLoop::isMain());
+    if (!success)
+        return;
+
+    auto transactions = m_establishedTransactions.add(&transactionIdentifier.connection(), HashSet<IDBIdentifier>());
+    transactions.iterator->value.add(transactionIdentifier);
+}
+
+void UniqueIDBDatabase::didResetTransaction(const IDBIdentifier& transactionIdentifier, bool success)
+{
+    ASSERT(RunLoop::isMain());
+    if (!success)
+        return;
+
+    auto transactions = m_establishedTransactions.find(&transactionIdentifier.connection());
+    if (transactions != m_establishedTransactions.end())
+        transactions.get()->value.remove(transactionIdentifier);
+}
+
+void UniqueIDBDatabase::resetAllTransactions(const DatabaseProcessIDBConnection& connection)
+{
+    ASSERT(RunLoop::isMain());
+    auto transactions = m_establishedTransactions.find(&connection);
+    if (transactions == m_establishedTransactions.end() || !m_acceptingNewRequests)
+        return;
+
+    for (auto& transactionIdentifier : transactions.get()->value) {
+        m_pendingTransactionRollbacks.add(transactionIdentifier);
+        if (!m_pendingTransactionRequests.contains(transactionIdentifier))
+            finalizeRollback(transactionIdentifier);
+    }
+}
+
+void UniqueIDBDatabase::finalizeRollback(const WebKit::IDBIdentifier& transactionId)
+{
+    ASSERT(RunLoop::isMain());
+    ASSERT(m_pendingTransactionRollbacks.contains(transactionId));
+    ASSERT(!m_pendingTransactionRequests.contains(transactionId));
+    rollbackTransaction(transactionId, [this, transactionId](bool) {
+        ASSERT(RunLoop::isMain());
+        if (m_pendingTransactionRequests.contains(transactionId))
+            return;
+
+        ASSERT(m_pendingTransactionRollbacks.contains(transactionId));
+        m_pendingTransactionRollbacks.remove(transactionId);
+        resetTransaction(transactionId, [this, transactionId](bool) {
+            if (m_acceptingNewRequests && m_connections.isEmpty() && m_pendingTransactionRollbacks.isEmpty()) {
+                shutdown(UniqueIDBDatabaseShutdownType::NormalShutdown);
+                DatabaseProcess::shared().removeUniqueIDBDatabase(*this);
+            }
+        });
+    });
+}
+
 String UniqueIDBDatabase::absoluteDatabaseDirectory() const
 {
     ASSERT(RunLoop::isMain());

Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.h (171703 => 171704)


--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.h	2014-07-28 22:19:11 UTC (rev 171703)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.h	2014-07-28 22:26:52 UTC (rev 171704)
@@ -185,10 +185,17 @@
     void didShutdownBackingStore(UniqueIDBDatabaseShutdownType);
     void didCompleteBoolRequest(uint64_t requestID, bool success);
 
+    void didEstablishTransaction(const IDBIdentifier& transactionIdentifier, bool success);
+    void didResetTransaction(const IDBIdentifier& transactionIdentifier, bool success);
+    void resetAllTransactions(const DatabaseProcessIDBConnection&);
+    void finalizeRollback(const IDBIdentifier& transactionId);
+
     bool m_acceptingNewRequests;
 
+    HashMap<const DatabaseProcessIDBConnection*, HashSet<IDBIdentifier>> m_establishedTransactions;
     Deque<RefPtr<AsyncRequest>> m_pendingMetadataRequests;
     HashMap<IDBIdentifier, RefPtr<AsyncRequest>> m_pendingTransactionRequests;
+    HashSet<IDBIdentifier> m_pendingTransactionRollbacks;
     HashMap<uint64_t, RefPtr<AsyncRequest>> m_pendingDatabaseTasks;
     RefPtr<AsyncRequest> m_pendingShutdownTask;
 

Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp (171703 => 171704)


--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp	2014-07-28 22:19:11 UTC (rev 171703)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp	2014-07-28 22:26:52 UTC (rev 171704)
@@ -391,6 +391,11 @@
         return false;
     }
 
+    if (!transaction->inProgress()) {
+        LOG_ERROR("Attempt to rollback a transaction that hasn't begun");
+        return false;
+    }
+
     return transaction->rollback();
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to