CrashTracer: com.apple.WebKit.Storage at WebCore::IDBServer::UniqueIDBDatabase::conne...
authorsihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Aug 2018 06:33:08 +0000 (06:33 +0000)
committersihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Aug 2018 06:33:08 +0000 (06:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188474

Reviewed by Chris Dumez.

UniqueIDBDatabaseConnection is refcounted by UniqueIDBDatabaseTransaction and it refcounts
UniqueIDBDatabaseTransaction. This cycle could make UniqueIDBDatabaseConnection outlives
UniqueIDBDatabase, so its reference to UniqueIDBDatabase may be stale. Calling a function
on a stale object is probably the reason of recent various storage process crashes in
indexedDB.

This patch makes m_database a WeakPtr and adds assertions that could help us debug the
crashes.

* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::closeAndDeleteDatabasesModifiedSince):
(WebCore::IDBServer::IDBServer::closeAndDeleteDatabasesForOrigins):
* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::commitTransaction):
(WebCore::IDBServer::UniqueIDBDatabase::abortTransaction):
* Modules/indexeddb/server/UniqueIDBDatabase.h:
* Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseConnection::UniqueIDBDatabaseConnection):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::~UniqueIDBDatabaseConnection):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::abortTransactionWithoutCallback):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::connectionClosedFromClient):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::confirmDidCloseFromServer):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::didFireVersionChangeEvent):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::didFinishHandlingVersionChange):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::createVersionChangeTransaction):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::establishTransaction):
(WebCore::IDBServer::UniqueIDBDatabaseConnection::didAbortTransaction):
* Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
(WebCore::IDBServer::UniqueIDBDatabaseConnection::database):
* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::UniqueIDBDatabaseTransaction):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::~UniqueIDBDatabaseTransaction):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::abort):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::commit):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::createObjectStore):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteObjectStore):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::renameObjectStore):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::clearObjectStore):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::createIndex):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteIndex):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::renameIndex):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::putOrAdd):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::getRecord):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::getAllRecords):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::getCount):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteRecord):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::openCursor):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::iterateCursor):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::objectStoreIdentifiers):
* Modules/indexeddb/shared/IDBResultData.cpp:
(WebCore::IDBResultData::openDatabaseSuccess):
(WebCore::IDBResultData::openDatabaseUpgradeNeeded):

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

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

index f139546..0309331 100644 (file)
@@ -1,3 +1,63 @@
+2018-08-12  Sihui Liu  <sihui_liu@apple.com>
+
+        CrashTracer: com.apple.WebKit.Storage at WebCore::IDBServer::UniqueIDBDatabase::connectionClosedFromClient(WebCore::IDBServer::UniqueIDBDatabaseConnection&)
+        https://bugs.webkit.org/show_bug.cgi?id=188474
+
+        Reviewed by Chris Dumez.
+
+        UniqueIDBDatabaseConnection is refcounted by UniqueIDBDatabaseTransaction and it refcounts
+        UniqueIDBDatabaseTransaction. This cycle could make UniqueIDBDatabaseConnection outlives
+        UniqueIDBDatabase, so its reference to UniqueIDBDatabase may be stale. Calling a function
+        on a stale object is probably the reason of recent various storage process crashes in
+        indexedDB.
+
+        This patch makes m_database a WeakPtr and adds assertions that could help us debug the
+        crashes.
+
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::closeAndDeleteDatabasesModifiedSince):
+        (WebCore::IDBServer::IDBServer::closeAndDeleteDatabasesForOrigins):
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::commitTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabase::abortTransaction):
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::UniqueIDBDatabaseConnection):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::~UniqueIDBDatabaseConnection):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::abortTransactionWithoutCallback):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::connectionClosedFromClient):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::confirmDidCloseFromServer):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::didFireVersionChangeEvent):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::didFinishHandlingVersionChange):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::createVersionChangeTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::establishTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::didAbortTransaction):
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::database):
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::UniqueIDBDatabaseTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::~UniqueIDBDatabaseTransaction):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::abort):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::commit):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::createObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::renameObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::clearObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::createIndex):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteIndex):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::renameIndex):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::putOrAdd):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::getRecord):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::getAllRecords):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::getCount):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteRecord):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::openCursor):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::iterateCursor):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::objectStoreIdentifiers):
+        * Modules/indexeddb/shared/IDBResultData.cpp:
+        (WebCore::IDBResultData::openDatabaseSuccess):
+        (WebCore::IDBResultData::openDatabaseUpgradeNeeded):
+
 2018-08-12  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
 
         Break reference cycle in ErrorEvent by using JSValueInWrappedObject
index 1b99452..059aeb5 100644 (file)
@@ -510,7 +510,7 @@ void IDBServer::closeAndDeleteDatabasesModifiedSince(WallTime modificationTime,
 
     HashSet<UniqueIDBDatabase*> openDatabases;
     for (auto* connection : m_databaseConnections.values())
-        openDatabases.add(&connection->database());
+        openDatabases.add(connection->database());
 
     for (auto& database : openDatabases)
         database->immediateCloseForUserDelete();
@@ -526,10 +526,13 @@ void IDBServer::closeAndDeleteDatabasesForOrigins(const Vector<SecurityOriginDat
 
     HashSet<UniqueIDBDatabase*> openDatabases;
     for (auto* connection : m_databaseConnections.values()) {
-        const auto& identifier = connection->database().identifier();
+        auto database = connection->database();
+        ASSERT(database);
+
+        const auto& identifier = database->identifier();
         for (auto& origin : origins) {
             if (identifier.isRelatedToOrigin(origin)) {
-                openDatabases.add(&connection->database());
+                openDatabases.add(database);
                 break;
             }
         }
index a6fede5..a4bbd02 100644 (file)
@@ -1302,7 +1302,7 @@ void UniqueIDBDatabase::commitTransaction(UniqueIDBDatabaseTransaction& transact
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::commitTransaction - %s", transaction.info().identifier().loggingString().utf8().data());
 
-    ASSERT(&transaction.databaseConnection().database() == this);
+    ASSERT(transaction.databaseConnection().database() == this);
 
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
@@ -1346,7 +1346,7 @@ void UniqueIDBDatabase::abortTransaction(UniqueIDBDatabaseTransaction& transacti
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::abortTransaction - %s", transaction.info().identifier().loggingString().utf8().data());
 
-    ASSERT(&transaction.databaseConnection().database() == this);
+    ASSERT(transaction.databaseConnection().database() == this);
 
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
index 9a8b1c5..f3b8788 100644 (file)
@@ -72,7 +72,7 @@ typedef Function<void(const IDBError&, const IDBGetResult&)> GetResultCallback;
 typedef Function<void(const IDBError&, const IDBGetAllResult&)> GetAllResultsCallback;
 typedef Function<void(const IDBError&, uint64_t)> CountCallback;
 
-class UniqueIDBDatabase {
+class UniqueIDBDatabase : public CanMakeWeakPtr<UniqueIDBDatabase> {
 public:
     UniqueIDBDatabase(IDBServer&, const IDBDatabaseIdentifier&);
     UniqueIDBDatabase(UniqueIDBDatabase&) = delete;
index 84015d8..2a40f52 100644 (file)
@@ -44,17 +44,18 @@ Ref<UniqueIDBDatabaseConnection> UniqueIDBDatabaseConnection::create(UniqueIDBDa
 }
 
 UniqueIDBDatabaseConnection::UniqueIDBDatabaseConnection(UniqueIDBDatabase& database, ServerOpenDBRequest& request)
-    : m_database(database)
+    : m_database(makeWeakPtr(database))
     , m_connectionToClient(request.connection())
     , m_openRequestIdentifier(request.requestData().requestIdentifier())
 {
-    m_database.server().registerDatabaseConnection(*this);
+    m_database->server().registerDatabaseConnection(*this);
     m_connectionToClient.registerDatabaseConnection(*this);
 }
 
 UniqueIDBDatabaseConnection::~UniqueIDBDatabaseConnection()
 {
-    m_database.server().unregisterDatabaseConnection(*this);
+    if (m_database)
+        m_database->server().unregisterDatabaseConnection(*this);
     m_connectionToClient.unregisterDatabaseConnection(*this);
 }
 
@@ -70,7 +71,11 @@ void UniqueIDBDatabaseConnection::abortTransactionWithoutCallback(UniqueIDBDatab
     const auto& transactionIdentifier = transaction.info().identifier();
     RefPtr<UniqueIDBDatabaseConnection> protectedThis(this);
 
-    m_database.abortTransaction(transaction, [this, protectedThis, transactionIdentifier](const IDBError&) {
+    ASSERT(m_database);
+    if (!m_database)
+        return;
+    
+    m_database->abortTransaction(transaction, [this, protectedThis, transactionIdentifier](const IDBError&) {
         ASSERT(m_transactionMap.contains(transactionIdentifier));
         m_transactionMap.remove(transactionIdentifier);
     });
@@ -87,28 +92,36 @@ void UniqueIDBDatabaseConnection::connectionClosedFromClient()
 {
     LOG(IndexedDB, "UniqueIDBDatabaseConnection::connectionClosedFromClient - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), identifier());
 
-    m_database.connectionClosedFromClient(*this);
+    ASSERT(m_database);
+    if (m_database)
+        m_database->connectionClosedFromClient(*this);
 }
 
 void UniqueIDBDatabaseConnection::confirmDidCloseFromServer()
 {
     LOG(IndexedDB, "UniqueIDBDatabaseConnection::confirmDidCloseFromServer - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), identifier());
 
-    m_database.confirmDidCloseFromServer(*this);
+    ASSERT(m_database);
+    if (m_database)
+        m_database->confirmDidCloseFromServer(*this);
 }
 
 void UniqueIDBDatabaseConnection::didFireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier)
 {
     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didFireVersionChangeEvent - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), identifier());
 
-    m_database.didFireVersionChangeEvent(*this, requestIdentifier);
+    ASSERT(m_database);
+    if (m_database)
+        m_database->didFireVersionChangeEvent(*this, requestIdentifier);
 }
 
 void UniqueIDBDatabaseConnection::didFinishHandlingVersionChange(const IDBResourceIdentifier& transactionIdentifier)
 {
     LOG(IndexedDB, "UniqueIDBDatabaseConnection::didFinishHandlingVersionChange - %s - %" PRIu64, transactionIdentifier.loggingString().utf8().data(), identifier());
 
-    m_database.didFinishHandlingVersionChange(*this, transactionIdentifier);
+    ASSERT(m_database);
+    if (m_database)
+        m_database->didFinishHandlingVersionChange(*this, transactionIdentifier);
 }
 
 void UniqueIDBDatabaseConnection::fireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion)
@@ -122,7 +135,7 @@ UniqueIDBDatabaseTransaction& UniqueIDBDatabaseConnection::createVersionChangeTr
     LOG(IndexedDB, "UniqueIDBDatabaseConnection::createVersionChangeTransaction - %s - %" PRIu64, m_openRequestIdentifier.loggingString().utf8().data(), identifier());
     ASSERT(!m_closePending);
 
-    IDBTransactionInfo info = IDBTransactionInfo::versionChange(m_connectionToClient, m_database.info(), newVersion);
+    IDBTransactionInfo info = IDBTransactionInfo::versionChange(m_connectionToClient, m_database->info(), newVersion);
 
     Ref<UniqueIDBDatabaseTransaction> transaction = UniqueIDBDatabaseTransaction::create(*this, info);
     m_transactionMap.set(transaction->info().identifier(), &transaction.get());
@@ -142,7 +155,9 @@ void UniqueIDBDatabaseConnection::establishTransaction(const IDBTransactionInfo&
 
     Ref<UniqueIDBDatabaseTransaction> transaction = UniqueIDBDatabaseTransaction::create(*this, info);
     m_transactionMap.set(transaction->info().identifier(), &transaction.get());
-    m_database.enqueueTransaction(WTFMove(transaction));
+
+    ASSERT(m_database);
+    m_database->enqueueTransaction(WTFMove(transaction));
 }
 
 void UniqueIDBDatabaseConnection::didAbortTransaction(UniqueIDBDatabaseTransaction& transaction, const IDBError& error)
@@ -152,7 +167,8 @@ void UniqueIDBDatabaseConnection::didAbortTransaction(UniqueIDBDatabaseTransacti
     auto transactionIdentifier = transaction.info().identifier();
     auto takenTransaction = m_transactionMap.take(transactionIdentifier);
 
-    ASSERT(takenTransaction || m_database.hardClosedForUserDelete());
+    ASSERT(m_database);
+    ASSERT(takenTransaction || m_database->hardClosedForUserDelete());
     if (takenTransaction)
         m_connectionToClient.didAbortTransaction(transactionIdentifier, error);
 }
index 2f1a29a..3a2564a 100644 (file)
@@ -32,6 +32,7 @@
 #include <wtf/Identified.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
@@ -52,7 +53,7 @@ public:
     ~UniqueIDBDatabaseConnection();
 
     const IDBResourceIdentifier& openRequestIdentifier() { return m_openRequestIdentifier; }
-    UniqueIDBDatabase& database() { return m_database; }
+    UniqueIDBDatabase* database() { return m_database.get(); }
     IDBConnectionToClient& connectionToClient() { return m_connectionToClient; }
 
     void connectionPendingCloseFromClient();
@@ -86,7 +87,7 @@ public:
 private:
     UniqueIDBDatabaseConnection(UniqueIDBDatabase&, ServerOpenDBRequest&);
 
-    UniqueIDBDatabase& m_database;
+    WeakPtr<UniqueIDBDatabase> m_database;
     IDBConnectionToClient& m_connectionToClient;
     IDBResourceIdentifier m_openRequestIdentifier;
 
index 214f8c2..f47c3b3 100644 (file)
@@ -47,16 +47,23 @@ UniqueIDBDatabaseTransaction::UniqueIDBDatabaseTransaction(UniqueIDBDatabaseConn
     : m_databaseConnection(connection)
     , m_transactionInfo(info)
 {
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+
     if (m_transactionInfo.mode() == IDBTransactionMode::Versionchange)
-        m_originalDatabaseInfo = std::make_unique<IDBDatabaseInfo>(m_databaseConnection->database().info());
+        m_originalDatabaseInfo = std::make_unique<IDBDatabaseInfo>(database->info());
 
-    m_databaseConnection->database().server().registerTransaction(*this);
+    database->server().registerTransaction(*this);
 }
 
 UniqueIDBDatabaseTransaction::~UniqueIDBDatabaseTransaction()
 {
-    m_databaseConnection->database().transactionDestroyed(*this);
-    m_databaseConnection->database().server().unregisterTransaction(*this);
+    auto database = m_databaseConnection->database();
+    if (!database)
+        return;
+
+    database->transactionDestroyed(*this);
+    database->server().unregisterTransaction(*this);
 }
 
 IDBDatabaseInfo* UniqueIDBDatabaseTransaction::originalDatabaseInfo() const
@@ -70,7 +77,11 @@ void UniqueIDBDatabaseTransaction::abort()
     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::abort");
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().abortTransaction(*this, [this, protectedThis](const IDBError& error) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+
+    database->abortTransaction(*this, [this, protectedThis](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::abort (callback)");
         m_databaseConnection->didAbortTransaction(*this, error);
     });
@@ -98,7 +109,11 @@ void UniqueIDBDatabaseTransaction::commit()
     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::commit");
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().commitTransaction(*this, [this, protectedThis](const IDBError& error) {
+
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+
+    database->commitTransaction(*this, [this, protectedThis](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::commit (callback)");
         m_databaseConnection->didCommitTransaction(*this, error);
     });
@@ -112,7 +127,11 @@ void UniqueIDBDatabaseTransaction::createObjectStore(const IDBRequestData& reque
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().createObjectStore(*this, info, [this, protectedThis, requestData](const IDBError& error) {
+
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+
+    database->createObjectStore(*this, info, [this, protectedThis, requestData](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createObjectStore (callback)");
         if (error.isNull())
             m_databaseConnection->didCreateObjectStore(IDBResultData::createObjectStoreSuccess(requestData.requestIdentifier()));
@@ -129,7 +148,11 @@ void UniqueIDBDatabaseTransaction::deleteObjectStore(const IDBRequestData& reque
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().deleteObjectStore(*this, objectStoreName, [this, protectedThis, requestData](const IDBError& error) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+
+    database->deleteObjectStore(*this, objectStoreName, [this, protectedThis, requestData](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteObjectStore (callback)");
         if (error.isNull())
             m_databaseConnection->didDeleteObjectStore(IDBResultData::deleteObjectStoreSuccess(requestData.requestIdentifier()));
@@ -146,7 +169,11 @@ void UniqueIDBDatabaseTransaction::renameObjectStore(const IDBRequestData& reque
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().renameObjectStore(*this, objectStoreIdentifier, newName, [this, protectedThis, requestData](const IDBError& error) {
+
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+
+    database->renameObjectStore(*this, objectStoreIdentifier, newName, [this, protectedThis, requestData](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::renameObjectStore (callback)");
         if (error.isNull())
             m_databaseConnection->didRenameObjectStore(IDBResultData::renameObjectStoreSuccess(requestData.requestIdentifier()));
@@ -162,7 +189,11 @@ void UniqueIDBDatabaseTransaction::clearObjectStore(const IDBRequestData& reques
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().clearObjectStore(*this, objectStoreIdentifier, [this, protectedThis, requestData](const IDBError& error) {
+
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+
+    database->clearObjectStore(*this, objectStoreIdentifier, [this, protectedThis, requestData](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::clearObjectStore (callback)");
         if (error.isNull())
             m_databaseConnection->didClearObjectStore(IDBResultData::clearObjectStoreSuccess(requestData.requestIdentifier()));
@@ -179,7 +210,11 @@ void UniqueIDBDatabaseTransaction::createIndex(const IDBRequestData& requestData
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().createIndex(*this, info, [this, protectedThis, requestData](const IDBError& error) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+
+    database->createIndex(*this, info, [this, protectedThis, requestData](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createIndex (callback)");
         if (error.isNull())
             m_databaseConnection->didCreateIndex(IDBResultData::createIndexSuccess(requestData.requestIdentifier()));
@@ -196,7 +231,11 @@ void UniqueIDBDatabaseTransaction::deleteIndex(const IDBRequestData& requestData
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().deleteIndex(*this, objectStoreIdentifier, indexName, [this, protectedThis, requestData](const IDBError& error) {
+
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+    
+    database->deleteIndex(*this, objectStoreIdentifier, indexName, [this, protectedThis, requestData](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createIndex (callback)");
         if (error.isNull())
             m_databaseConnection->didDeleteIndex(IDBResultData::deleteIndexSuccess(requestData.requestIdentifier()));
@@ -213,7 +252,11 @@ void UniqueIDBDatabaseTransaction::renameIndex(const IDBRequestData& requestData
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().renameIndex(*this, objectStoreIdentifier, indexIdentifier, newName, [this, protectedThis, requestData](const IDBError& error) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+    
+    database->renameIndex(*this, objectStoreIdentifier, indexIdentifier, newName, [this, protectedThis, requestData](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::renameIndex (callback)");
         if (error.isNull())
             m_databaseConnection->didRenameIndex(IDBResultData::renameIndexSuccess(requestData.requestIdentifier()));
@@ -231,7 +274,11 @@ void UniqueIDBDatabaseTransaction::putOrAdd(const IDBRequestData& requestData, c
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().putOrAdd(requestData, keyData, value, overwriteMode, [this, protectedThis, requestData](const IDBError& error, const IDBKeyData& key) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+    
+    database->putOrAdd(requestData, keyData, value, overwriteMode, [this, protectedThis, requestData](const IDBError& error, const IDBKeyData& key) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::putOrAdd (callback)");
 
         if (error.isNull())
@@ -248,7 +295,11 @@ void UniqueIDBDatabaseTransaction::getRecord(const IDBRequestData& requestData,
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().getRecord(requestData, getRecordData, [this, protectedThis, requestData](const IDBError& error, const IDBGetResult& result) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+    
+    database->getRecord(requestData, getRecordData, [this, protectedThis, requestData](const IDBError& error, const IDBGetResult& result) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getRecord (callback)");
 
         if (error.isNull())
@@ -265,7 +316,11 @@ void UniqueIDBDatabaseTransaction::getAllRecords(const IDBRequestData& requestDa
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().getAllRecords(requestData, getAllRecordsData, [this, protectedThis, requestData](const IDBError& error, const IDBGetAllResult& result) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+    
+    database->getAllRecords(requestData, getAllRecordsData, [this, protectedThis, requestData](const IDBError& error, const IDBGetAllResult& result) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getAllRecords (callback)");
 
         if (error.isNull())
@@ -282,7 +337,11 @@ void UniqueIDBDatabaseTransaction::getCount(const IDBRequestData& requestData, c
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().getCount(requestData, keyRangeData, [this, protectedThis, requestData](const IDBError& error, uint64_t count) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+    
+    database->getCount(requestData, keyRangeData, [this, protectedThis, requestData](const IDBError& error, uint64_t count) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getCount (callback)");
 
         if (error.isNull())
@@ -299,7 +358,11 @@ void UniqueIDBDatabaseTransaction::deleteRecord(const IDBRequestData& requestDat
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().deleteRecord(requestData, keyRangeData, [this, protectedThis, requestData](const IDBError& error) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+    
+    database->deleteRecord(requestData, keyRangeData, [this, protectedThis, requestData](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteRecord (callback)");
 
         if (error.isNull())
@@ -316,7 +379,11 @@ void UniqueIDBDatabaseTransaction::openCursor(const IDBRequestData& requestData,
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().openCursor(requestData, info, [this, protectedThis, requestData](const IDBError& error, const IDBGetResult& result) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+    
+    database->openCursor(requestData, info, [this, protectedThis, requestData](const IDBError& error, const IDBGetResult& result) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::openCursor (callback)");
 
         if (error.isNull())
@@ -333,7 +400,11 @@ void UniqueIDBDatabaseTransaction::iterateCursor(const IDBRequestData& requestDa
     ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
 
     RefPtr<UniqueIDBDatabaseTransaction> protectedThis(this);
-    m_databaseConnection->database().iterateCursor(requestData, data, [this, protectedThis, requestData](const IDBError& error, const IDBGetResult& result) {
+    
+    auto database = m_databaseConnection->database();
+    ASSERT(database);
+    
+    database->iterateCursor(requestData, data, [this, protectedThis, requestData](const IDBError& error, const IDBGetResult& result) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::iterateCursor (callback)");
 
         if (error.isNull())
@@ -348,7 +419,7 @@ const Vector<uint64_t>& UniqueIDBDatabaseTransaction::objectStoreIdentifiers()
     if (!m_objectStoreIdentifiers.isEmpty())
         return m_objectStoreIdentifiers;
 
-    auto& info = m_databaseConnection->database().info();
+    auto& info = m_databaseConnection->database()->info();
     for (auto objectStoreName : info.objectStoreNames()) {
         auto objectStoreInfo = info.infoForExistingObjectStore(objectStoreName);
         ASSERT(objectStoreInfo);
index 6c6ae6b..7ff08ee 100644 (file)
@@ -111,7 +111,7 @@ IDBResultData IDBResultData::openDatabaseSuccess(const IDBResourceIdentifier& re
     IDBResultData result { requestIdentifier };
     result.m_type = IDBResultType::OpenDatabaseSuccess;
     result.m_databaseConnectionIdentifier = connection.identifier();
-    result.m_databaseInfo = std::make_unique<IDBDatabaseInfo>(connection.database().info());
+    result.m_databaseInfo = std::make_unique<IDBDatabaseInfo>(connection.database()->info());
     return result;
 }
 
@@ -121,7 +121,7 @@ IDBResultData IDBResultData::openDatabaseUpgradeNeeded(const IDBResourceIdentifi
     IDBResultData result { requestIdentifier };
     result.m_type = IDBResultType::OpenDatabaseUpgradeNeeded;
     result.m_databaseConnectionIdentifier = transaction.databaseConnection().identifier();
-    result.m_databaseInfo = std::make_unique<IDBDatabaseInfo>(transaction.databaseConnection().database().info());
+    result.m_databaseInfo = std::make_unique<IDBDatabaseInfo>(transaction.databaseConnection().database()->info());
     result.m_transactionInfo = std::make_unique<IDBTransactionInfo>(transaction.info());
     return result;
 }