+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.
ASSERT(m_inProgressTransactions.isEmpty());
ASSERT(m_pendingTransactions.isEmpty());
ASSERT(m_openDatabaseConnections.isEmpty());
+ ASSERT(m_closePendingDatabaseConnections.isEmpty());
}
const IDBDatabaseInfo& UniqueIDBDatabase::info() const
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());
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()
ASSERT(isMainThread());
LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformCommitTransaction");
- inProgressTransactionCompleted(transactionIdentifier);
-
performErrorCallback(callbackIdentifier, error);
+
+ inProgressTransactionCompleted(transactionIdentifier);
}
void UniqueIDBDatabase::abortTransaction(UniqueIDBDatabaseTransaction& transaction, ErrorCallback callback)
m_databaseInfo = std::make_unique<IDBDatabaseInfo>(*m_versionChangeTransaction->originalDatabaseInfo());
}
- inProgressTransactionCompleted(transactionIdentifier);
-
performErrorCallback(callbackIdentifier, error);
+
+ inProgressTransactionCompleted(transactionIdentifier);
}
void UniqueIDBDatabase::transactionDestroyed(UniqueIDBDatabaseTransaction& transaction)
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();
}
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);