Modern IDB: Some w3c objectstore tests crash under GuardMalloc.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Feb 2016 00:23:38 +0000 (00:23 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Feb 2016 00:23:38 +0000 (00:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=154460

Reviewed by Alex Christensen.

No new tests (Covered by existing tests).

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::~UniqueIDBDatabase):
(WebCore::IDBServer::UniqueIDBDatabase::performCurrentDeleteOperation):
(WebCore::IDBServer::UniqueIDBDatabase::didDeleteBackingStore):  Don't delete the UniqueIDBDatabase yet
  if there are still any connections pending close.
(WebCore::IDBServer::UniqueIDBDatabase::didPerformCommitTransaction):
(WebCore::IDBServer::UniqueIDBDatabase::didPerformAbortTransaction):
(WebCore::IDBServer::UniqueIDBDatabase::inProgressTransactionCompleted): It's possible that with this
  transaction completing, and a connection finished its close process, that the UniqueIDBDatabase is
  now ready to be deleted.

* Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseConnection::abortTransactionWithoutCallback):
* Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:

* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::abortWithoutCallback):

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

Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp

index c138c30..4368044 100644 (file)
@@ -1,3 +1,30 @@
+2016-02-24  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: Some w3c objectstore tests crash under GuardMalloc.
+        https://bugs.webkit.org/show_bug.cgi?id=154460
+
+        Reviewed by Alex Christensen.
+
+        No new tests (Covered by existing tests).
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::~UniqueIDBDatabase):
+        (WebCore::IDBServer::UniqueIDBDatabase::performCurrentDeleteOperation):
+        (WebCore::IDBServer::UniqueIDBDatabase::didDeleteBackingStore):  Don't delete the UniqueIDBDatabase yet 
+          if there are still any connections pending close.
+        (WebCore::IDBServer::UniqueIDBDatabase::didPerformCommitTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabase::didPerformAbortTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabase::inProgressTransactionCompleted): It's possible that with this
+          transaction completing, and a connection finished its close process, that the UniqueIDBDatabase is
+          now ready to be deleted.
+
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::abortTransactionWithoutCallback):
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::abortWithoutCallback):
+
 2016-02-24  Konstantin Tokarev  <annulen@yandex.ru>
 
         [cmake] Moved PRE/POST_BUILD_COMMAND to WEBKIT_FRAMEWORK.
index d907c8e..575883e 100644 (file)
@@ -59,6 +59,7 @@ UniqueIDBDatabase::~UniqueIDBDatabase()
     ASSERT(m_inProgressTransactions.isEmpty());
     ASSERT(m_pendingTransactions.isEmpty());
     ASSERT(m_openDatabaseConnections.isEmpty());
+    ASSERT(m_closePendingDatabaseConnections.isEmpty());
 }
 
 const IDBDatabaseInfo& UniqueIDBDatabase::info() const
@@ -181,12 +182,8 @@ void UniqueIDBDatabase::performCurrentDeleteOperation()
         return;
     }
 
-    // Even though we have no open database connections, we might have close-pending database connections
-    // that are waiting on transactions to complete.
-    if (!m_inProgressTransactions.isEmpty()) {
-        ASSERT(!m_closePendingDatabaseConnections.isEmpty());
+    if (!m_inProgressTransactions.isEmpty())
         return;
-    }
 
     ASSERT(!hasAnyPendingCallbacks());
     ASSERT(m_pendingTransactions.isEmpty());
@@ -241,10 +238,12 @@ void UniqueIDBDatabase::didDeleteBackingStore()
     m_deletePending = false;
     m_deleteBackingStoreInProgress = false;
 
-    if (m_pendingOpenDBRequests.isEmpty())
-        m_server.deleteUniqueIDBDatabase(*this);
-    else
-        invokeOperationAndTransactionTimer();
+    if (m_closePendingDatabaseConnections.isEmpty()) {
+        if (m_pendingOpenDBRequests.isEmpty())
+            m_server.deleteUniqueIDBDatabase(*this);
+        else
+            invokeOperationAndTransactionTimer();
+    }
 }
 
 void UniqueIDBDatabase::handleDatabaseOperations()
@@ -978,9 +977,9 @@ void UniqueIDBDatabase::didPerformCommitTransaction(uint64_t callbackIdentifier,
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformCommitTransaction");
 
-    inProgressTransactionCompleted(transactionIdentifier);
-
     performErrorCallback(callbackIdentifier, error);
+
+    inProgressTransactionCompleted(transactionIdentifier);
 }
 
 void UniqueIDBDatabase::abortTransaction(UniqueIDBDatabaseTransaction& transaction, ErrorCallback callback)
@@ -1028,9 +1027,9 @@ void UniqueIDBDatabase::didPerformAbortTransaction(uint64_t callbackIdentifier,
         m_databaseInfo = std::make_unique<IDBDatabaseInfo>(*m_versionChangeTransaction->originalDatabaseInfo());
     }
 
-    inProgressTransactionCompleted(transactionIdentifier);
-
     performErrorCallback(callbackIdentifier, error);
+
+    inProgressTransactionCompleted(transactionIdentifier);
 }
 
 void UniqueIDBDatabase::transactionDestroyed(UniqueIDBDatabaseTransaction& transaction)
@@ -1244,6 +1243,13 @@ void UniqueIDBDatabase::inProgressTransactionCompleted(const IDBResourceIdentifi
     if (!transaction->databaseConnection().hasNonFinishedTransactions())
         m_closePendingDatabaseConnections.remove(&transaction->databaseConnection());
 
+    // It's possible that this database had its backing store deleted but there were a few outstanding asynchronous operations.
+    // If this transaction completing was the last of those operations, we can finally delete this UniqueIDBDatabase.
+    if (m_closePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty() && !m_databaseInfo) {
+        m_server.deleteUniqueIDBDatabase(*this);
+        return;
+    }
+
     // Previously blocked operations might be runnable.
     invokeOperationAndTransactionTimer();
 }
index 75c3637..4aa8a84 100644 (file)
@@ -66,6 +66,14 @@ bool UniqueIDBDatabaseConnection::hasNonFinishedTransactions() const
     return !m_transactionMap.isEmpty();
 }
 
+void UniqueIDBDatabaseConnection::abortTransactionWithoutCallback(UniqueIDBDatabaseTransaction& transaction)
+{
+    ASSERT(m_transactionMap.contains(transaction.info().identifier()));
+    auto takenTransaction = m_transactionMap.take(transaction.info().identifier());
+
+    m_database.abortTransaction(*takenTransaction, [](const IDBError&) { });
+}
+
 void UniqueIDBDatabaseConnection::connectionClosedFromClient()
 {
     LOG(IndexedDB, "UniqueIDBDatabaseConnection::connectionClosedFromClient - %" PRIu64, m_identifier);
index b4f87bb..1bbced9 100644 (file)
@@ -73,6 +73,8 @@ public:
     void didDeleteIndex(const IDBResultData&);
     void didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier);
 
+    void abortTransactionWithoutCallback(UniqueIDBDatabaseTransaction&);
+
 private:
     UniqueIDBDatabaseConnection(UniqueIDBDatabase&, IDBConnectionToClient&);
 
index 41ef8c2..cd26b39 100644 (file)
@@ -79,7 +79,7 @@ void UniqueIDBDatabaseTransaction::abortWithoutCallback()
 {
     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::abortWithoutCallback");
 
-    m_databaseConnection->database().abortTransaction(*this, [](const IDBError&) { });
+    m_databaseConnection->abortTransactionWithoutCallback(*this);
 }
 
 bool UniqueIDBDatabaseTransaction::isVersionChange() const