Include WAL and SHM file size in IDB database size computation
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Mar 2019 01:24:52 +0000 (01:24 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Mar 2019 01:24:52 +0000 (01:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195688

Reviewed by Brady Eidson.

Source/WebCore:

Count WAL and SHM files as part of IDB quota checks.
This makes some IDB tests go over the testing quota which then
triggers some IDB tasks to happen sooner than other write IDB tasks.
The IDB implementation requires these tasks to remain ordered.
In case a write task is pending quota check, queue all tasks,
write or read, to keep the order.

This patch specials case aborting a transaction.
In case it is called as part of clearing a database,
the task should not be queued and all pending tasks are errored.
When transaction is aborted by the web page, queue the task.

When we can make a decision to run tasks with size 0,
do not check quota. This ensures that read operations
succeed even if we are above quota.

Covered by existing tests.

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::waitForRequestSpaceCompletion):
(WebCore::IDBServer::UniqueIDBDatabase::deleteObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::clearObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::deleteIndex):
(WebCore::IDBServer::UniqueIDBDatabase::getRecord):
(WebCore::IDBServer::UniqueIDBDatabase::getAllRecords):
(WebCore::IDBServer::UniqueIDBDatabase::getCount):
(WebCore::IDBServer::UniqueIDBDatabase::deleteRecord):
(WebCore::IDBServer::UniqueIDBDatabase::openCursor):
(WebCore::IDBServer::UniqueIDBDatabase::iterateCursor):
(WebCore::IDBServer::UniqueIDBDatabase::commitTransaction):
* Modules/indexeddb/server/UniqueIDBDatabase.h:
* Modules/webdatabase/DatabaseTracker.cpp:
(WebCore::DatabaseTracker::usage):
* platform/sql/SQLiteFileSystem.cpp:
(WebCore::SQLiteFileSystem::getDatabaseFileSize):
* storage/StorageQuotaManager.h:
* storage/StorageQuotaManager.cpp:
(WebCore::StorageQuotaManager::requestSpace):

LayoutTests:

* storage/websql/open-database-creation-callback.html:
Bump quota for this test since WAL files are not included in quota computation.

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

LayoutTests/ChangeLog
LayoutTests/storage/websql/open-database-creation-callback.html
Source/WebCore/ChangeLog
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/UniqueIDBDatabaseTransaction.cpp
Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp
Source/WebCore/platform/sql/SQLiteFileSystem.cpp
Source/WebCore/storage/StorageQuotaManager.cpp
Source/WebCore/storage/StorageQuotaManager.h

index 39e321a..f57d105 100644 (file)
@@ -1,3 +1,13 @@
+2019-03-20  Youenn Fablet  <youenn@apple.com>
+
+        Include WAL and SHM file size in IDB database size computation
+        https://bugs.webkit.org/show_bug.cgi?id=195688
+
+        Reviewed by Brady Eidson.
+
+        * storage/websql/open-database-creation-callback.html:
+        Bump quota for this test since WAL files are not included in quota computation.
+
 2019-03-20  Devin Rousso  <drousso@apple.com>
 
         Web Inspector: Timeline should show when events preventDefault() was called on an event or not
index 64af63f..0d2b917 100644 (file)
@@ -16,7 +16,7 @@ function runTest()
 {
     if (window.testRunner) {
         testRunner.clearAllDatabases();
-        testRunner.setDatabaseQuota(32768);
+        testRunner.setDatabaseQuota(327680);
         testRunner.dumpDatabaseCallbacks();
         testRunner.dumpAsText();
         testRunner.waitUntilDone();
index 44c7449..70853d3 100644 (file)
@@ -1,3 +1,49 @@
+2019-03-20  Youenn Fablet  <youenn@apple.com>
+
+        Include WAL and SHM file size in IDB database size computation
+        https://bugs.webkit.org/show_bug.cgi?id=195688
+
+        Reviewed by Brady Eidson.
+
+        Count WAL and SHM files as part of IDB quota checks.
+        This makes some IDB tests go over the testing quota which then
+        triggers some IDB tasks to happen sooner than other write IDB tasks.
+        The IDB implementation requires these tasks to remain ordered.
+        In case a write task is pending quota check, queue all tasks,
+        write or read, to keep the order.
+
+        This patch specials case aborting a transaction.
+        In case it is called as part of clearing a database,
+        the task should not be queued and all pending tasks are errored.
+        When transaction is aborted by the web page, queue the task.
+
+        When we can make a decision to run tasks with size 0,
+        do not check quota. This ensures that read operations
+        succeed even if we are above quota.
+
+        Covered by existing tests.
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::waitForRequestSpaceCompletion):
+        (WebCore::IDBServer::UniqueIDBDatabase::deleteObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::clearObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::deleteIndex):
+        (WebCore::IDBServer::UniqueIDBDatabase::getRecord):
+        (WebCore::IDBServer::UniqueIDBDatabase::getAllRecords):
+        (WebCore::IDBServer::UniqueIDBDatabase::getCount):
+        (WebCore::IDBServer::UniqueIDBDatabase::deleteRecord):
+        (WebCore::IDBServer::UniqueIDBDatabase::openCursor):
+        (WebCore::IDBServer::UniqueIDBDatabase::iterateCursor):
+        (WebCore::IDBServer::UniqueIDBDatabase::commitTransaction):
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+        * Modules/webdatabase/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::usage):
+        * platform/sql/SQLiteFileSystem.cpp:
+        (WebCore::SQLiteFileSystem::getDatabaseFileSize):
+        * storage/StorageQuotaManager.h:
+        * storage/StorageQuotaManager.cpp:
+        (WebCore::StorageQuotaManager::requestSpace):
+
 2019-03-20  Devin Rousso  <drousso@apple.com>
 
         Web Inspector: Timeline should show when events preventDefault() was called on an event or not
index 8f0f796..0961d9c 100644 (file)
@@ -199,6 +199,11 @@ void UniqueIDBDatabase::requestSpace(uint64_t taskSize, const char* taskName, Co
     });
 }
 
+void UniqueIDBDatabase::waitForRequestSpaceCompletion(CompletionHandler<void(Optional<IDBError>&&)>&& callback)
+{
+    requestSpace(0, "", WTFMove(callback));
+}
+
 void UniqueIDBDatabase::performCurrentOpenOperation()
 {
     LOG(IndexedDB, "(main) UniqueIDBDatabase::performCurrentOpenOperation (%p)", this);
@@ -779,7 +784,7 @@ void UniqueIDBDatabase::createObjectStore(UniqueIDBDatabaseTransaction& transact
     auto taskSize = defaultWriteOperationCost + estimateSize(info);
     requestSpace(taskSize, "createObjectStore", [this, taskSize, transaction = makeRef(transaction), info, callback = WTFMove(callback)](auto error) mutable {
         if (error) {
-            callback(WTFMove(error.value()));
+            callback(WTFMove(*error));
             return;
         }
         this->createObjectStoreAfterQuotaCheck(taskSize, transaction.get(), info, WTFMove(callback));
@@ -823,6 +828,17 @@ void UniqueIDBDatabase::deleteObjectStore(UniqueIDBDatabaseTransaction& transact
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteObjectStore");
 
+    waitForRequestSpaceCompletion([this, transaction = makeRef(transaction), objectStoreName, callback = WTFMove(callback)](auto error) mutable {
+        if (error) {
+            callback(WTFMove(*error));
+            return;
+        }
+        this->deleteObjectStoreAfterQuotaCheck(transaction, objectStoreName, WTFMove(callback));
+    });
+}
+
+void UniqueIDBDatabase::deleteObjectStoreAfterQuotaCheck(UniqueIDBDatabaseTransaction& transaction, const String& objectStoreName, ErrorCallback callback)
+{
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
@@ -867,7 +883,7 @@ void UniqueIDBDatabase::renameObjectStore(UniqueIDBDatabaseTransaction& transact
     auto taskSize = defaultWriteOperationCost + newName.sizeInBytes();
     requestSpace(taskSize, "renameObjectStore", [this, taskSize, transaction = makeRef(transaction), objectStoreIdentifier, newName, callback = WTFMove(callback)](auto error) mutable {
         if (error) {
-            callback(WTFMove(error.value()));
+            callback(WTFMove(*error));
             return;
         }
         this->renameObjectStoreAfterQuotaCheck(taskSize, transaction.get(), objectStoreIdentifier, newName, WTFMove(callback));
@@ -917,6 +933,17 @@ void UniqueIDBDatabase::clearObjectStore(UniqueIDBDatabaseTransaction& transacti
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::clearObjectStore");
 
+    waitForRequestSpaceCompletion([this, transaction = makeRef(transaction), objectStoreIdentifier, callback = WTFMove(callback)](auto error) mutable {
+        if (error) {
+            callback(WTFMove(*error));
+            return;
+        }
+        this->clearObjectStoreAfetQuotaCheck(transaction, objectStoreIdentifier, WTFMove(callback));
+    });
+}
+
+void UniqueIDBDatabase::clearObjectStoreAfetQuotaCheck(UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, ErrorCallback callback)
+{
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
@@ -951,7 +978,7 @@ void UniqueIDBDatabase::createIndex(UniqueIDBDatabaseTransaction& transaction, c
     auto taskSize = defaultWriteOperationCost + estimateSize(info);
     requestSpace(taskSize, "createIndex", [this, taskSize, transaction = makeRef(transaction), info, callback = WTFMove(callback)](auto error) mutable {
         if (error) {
-            callback(WTFMove(error.value()));
+            callback(WTFMove(*error));
             return;
         }
         this->createIndexAfterQuotaCheck(taskSize, transaction.get(), info, WTFMove(callback));
@@ -997,6 +1024,17 @@ void UniqueIDBDatabase::deleteIndex(UniqueIDBDatabaseTransaction& transaction, u
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteIndex");
 
+    waitForRequestSpaceCompletion([this, transaction = makeRef(transaction), objectStoreIdentifier, indexName, callback = WTFMove(callback)](auto error) mutable {
+        if (error) {
+            callback(WTFMove(*error));
+            return;
+        }
+        this->deleteIndexAfterQuotaCheck(transaction, objectStoreIdentifier, indexName, WTFMove(callback));
+    });
+}
+
+void UniqueIDBDatabase::deleteIndexAfterQuotaCheck(UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, const String& indexName, ErrorCallback callback)
+{
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
@@ -1050,7 +1088,7 @@ void UniqueIDBDatabase::renameIndex(UniqueIDBDatabaseTransaction& transaction, u
     auto taskSize = defaultWriteOperationCost + newName.sizeInBytes();
     requestSpace(taskSize, "renameIndex", [this, taskSize, transaction = makeRef(transaction), objectStoreIdentifier, indexIdentifier, newName, callback = WTFMove(callback)](auto error) mutable {
         if (error) {
-            callback(WTFMove(error.value()));
+            callback(WTFMove(*error));
             return;
         }
         this->renameIndexAfterQuotaCheck(taskSize, transaction.get(), objectStoreIdentifier, indexIdentifier, newName, WTFMove(callback));
@@ -1116,7 +1154,7 @@ void UniqueIDBDatabase::putOrAdd(const IDBRequestData& requestData, const IDBKey
     auto taskSize = defaultWriteOperationCost + estimateSize(keyData) + estimateSize(value);
     requestSpace(taskSize, "putOrAdd", [this, taskSize, requestData, keyData, value, callback = WTFMove(callback), overwriteMode](auto error) mutable {
         if (error) {
-            callback(WTFMove(error.value()), { });
+            callback(WTFMove(*error), { });
             return;
         }
         this->putOrAddAfterQuotaCheck(taskSize, requestData, keyData, value, overwriteMode, WTFMove(callback));
@@ -1265,6 +1303,17 @@ void UniqueIDBDatabase::getRecord(const IDBRequestData& requestData, const IDBGe
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::getRecord");
 
+    waitForRequestSpaceCompletion([this, requestData, getRecordData, callback = WTFMove(callback)](auto error) mutable {
+        if (error) {
+            callback(WTFMove(*error), { });
+            return;
+        }
+        this->getRecordAfterQuotaCheck(requestData, getRecordData, WTFMove(callback));
+    });
+}
+
+void UniqueIDBDatabase::getRecordAfterQuotaCheck(const IDBRequestData& requestData, const IDBGetRecordData& getRecordData, GetResultCallback callback)
+{
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
@@ -1280,6 +1329,17 @@ void UniqueIDBDatabase::getAllRecords(const IDBRequestData& requestData, const I
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::getAllRecords");
 
+    waitForRequestSpaceCompletion([this, requestData, getAllRecordsData, callback = WTFMove(callback)](auto error) mutable {
+        if (error) {
+            callback(WTFMove(*error), { });
+            return;
+        }
+        this->getAllRecordsAfterQuotaCheck(requestData, getAllRecordsData, WTFMove(callback));
+    });
+}
+
+void UniqueIDBDatabase::getAllRecordsAfterQuotaCheck(const IDBRequestData& requestData, const IDBGetAllRecordsData& getAllRecordsData, GetAllResultsCallback callback)
+{
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
@@ -1347,6 +1407,17 @@ void UniqueIDBDatabase::getCount(const IDBRequestData& requestData, const IDBKey
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::getCount");
 
+    waitForRequestSpaceCompletion([this, requestData, range, callback = WTFMove(callback)](auto error) mutable {
+        if (error) {
+            callback(WTFMove(*error), { });
+            return;
+        }
+        this->getCountAfterQuotaCheck(requestData, range, WTFMove(callback));
+    });
+}
+
+void UniqueIDBDatabase::getCountAfterQuotaCheck(const IDBRequestData& requestData, const IDBKeyRangeData& range, CountCallback callback)
+{
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
@@ -1380,6 +1451,17 @@ void UniqueIDBDatabase::deleteRecord(const IDBRequestData& requestData, const ID
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteRecord");
 
+    waitForRequestSpaceCompletion([this, requestData, keyRangeData, callback = WTFMove(callback)](auto error) mutable {
+        if (error) {
+            callback(WTFMove(*error));
+            return;
+        }
+        this->deleteRecordAfterQuotaCheck(requestData, keyRangeData, WTFMove(callback));
+    });
+}
+
+void UniqueIDBDatabase::deleteRecordAfterQuotaCheck(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData, ErrorCallback callback)
+{
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
@@ -1409,6 +1491,17 @@ void UniqueIDBDatabase::openCursor(const IDBRequestData& requestData, const IDBC
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::openCursor");
 
+    waitForRequestSpaceCompletion([this, requestData, info, callback = WTFMove(callback)](auto error) mutable {
+        if (error) {
+            callback(WTFMove(*error), { });
+            return;
+        }
+        this->openCursorAfterQuotaCheck(requestData, info, WTFMove(callback));
+    });
+}
+
+void UniqueIDBDatabase::openCursorAfterQuotaCheck(const IDBRequestData& requestData, const IDBCursorInfo& info, GetResultCallback callback)
+{
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
@@ -1439,6 +1532,17 @@ void UniqueIDBDatabase::iterateCursor(const IDBRequestData& requestData, const I
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::iterateCursor");
 
+    waitForRequestSpaceCompletion([this, requestData, data, callback = WTFMove(callback)](auto error) mutable {
+        if (error) {
+            callback(WTFMove(*error), { });
+            return;
+        }
+        this->iterateCursorAfterQuotaCheck(requestData, data, WTFMove(callback));
+    });
+}
+
+void UniqueIDBDatabase::iterateCursorAfterQuotaCheck(const IDBRequestData& requestData, const IDBIterateCursorData& data, GetResultCallback callback)
+{
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
@@ -1501,6 +1605,17 @@ void UniqueIDBDatabase::commitTransaction(UniqueIDBDatabaseTransaction& transact
 
     ASSERT(transaction.databaseConnection().database() == this);
 
+    waitForRequestSpaceCompletion([this, transaction = makeRef(transaction), callback = WTFMove(callback)](auto error) mutable {
+        if (error) {
+            callback(WTFMove(*error));
+            return;
+        }
+        this->commitTransactionAfterQuotaCheck(transaction, WTFMove(callback));
+    });
+}
+
+void UniqueIDBDatabase::commitTransactionAfterQuotaCheck(UniqueIDBDatabaseTransaction& transaction, ErrorCallback callback)
+{
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
@@ -1538,13 +1653,24 @@ void UniqueIDBDatabase::didPerformCommitTransaction(uint64_t callbackIdentifier,
     transactionCompleted(m_finishingTransactions.take(transactionIdentifier));
 }
 
-void UniqueIDBDatabase::abortTransaction(UniqueIDBDatabaseTransaction& transaction, ErrorCallback callback)
+void UniqueIDBDatabase::abortTransaction(UniqueIDBDatabaseTransaction& transaction, WaitForPendingTasks waitForPendingTasks, ErrorCallback callback)
 {
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::abortTransaction - %s", transaction.info().identifier().loggingString().utf8().data());
 
     ASSERT(transaction.databaseConnection().database() == this);
 
+    if (waitForPendingTasks == WaitForPendingTasks::Yes) {
+        waitForRequestSpaceCompletion([this, transaction = makeRef(transaction), callback = WTFMove(callback)](auto&& error) mutable {
+            if (error) {
+                callback(WTFMove(*error));
+                return;
+            }
+            this->abortTransaction(transaction, WaitForPendingTasks::No, WTFMove(callback));
+        });
+        return;
+    }
+
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback));
     if (!callbackID)
         return;
index 683ae83..bce6745 100644 (file)
@@ -101,7 +101,10 @@ public:
     void openCursor(const IDBRequestData&, const IDBCursorInfo&, GetResultCallback);
     void iterateCursor(const IDBRequestData&, const IDBIterateCursorData&, GetResultCallback);
     void commitTransaction(UniqueIDBDatabaseTransaction&, ErrorCallback);
-    void abortTransaction(UniqueIDBDatabaseTransaction&, ErrorCallback);
+
+    enum class WaitForPendingTasks { No, Yes };
+    void abortTransaction(UniqueIDBDatabaseTransaction&, WaitForPendingTasks, ErrorCallback);
+
     void didFinishHandlingVersionChange(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& transactionIdentifier);
     void transactionDestroyed(UniqueIDBDatabaseTransaction&);
     void connectionClosedFromClient(UniqueIDBDatabaseConnection&);
@@ -152,6 +155,17 @@ private:
     void createIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, const IDBIndexInfo&, ErrorCallback);
     void renameIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, ErrorCallback);
     void putOrAddAfterQuotaCheck(uint64_t taskSize, const IDBRequestData&, const IDBKeyData&, const IDBValue&, IndexedDB::ObjectStoreOverwriteMode, KeyDataCallback);
+    void deleteRecordAfterQuotaCheck(const IDBRequestData&, const IDBKeyRangeData&, ErrorCallback);
+
+    void deleteObjectStoreAfterQuotaCheck(UniqueIDBDatabaseTransaction&, const String& objectStoreName, ErrorCallback);
+    void clearObjectStoreAfetQuotaCheck(UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, ErrorCallback);
+    void deleteIndexAfterQuotaCheck(UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, const String&, ErrorCallback);
+    void getRecordAfterQuotaCheck(const IDBRequestData&, const IDBGetRecordData&, GetResultCallback);
+    void getAllRecordsAfterQuotaCheck(const IDBRequestData&, const IDBGetAllRecordsData&, GetAllResultsCallback);
+    void getCountAfterQuotaCheck(const IDBRequestData&, const IDBKeyRangeData&, CountCallback);
+    void openCursorAfterQuotaCheck(const IDBRequestData&, const IDBCursorInfo&, GetResultCallback);
+    void iterateCursorAfterQuotaCheck(const IDBRequestData&, const IDBIterateCursorData&, GetResultCallback);
+    void commitTransactionAfterQuotaCheck(UniqueIDBDatabaseTransaction&, ErrorCallback);
 
     // Database thread operations
     void deleteBackingStore(const IDBDatabaseIdentifier&);
@@ -240,6 +254,7 @@ private:
     void notifyServerAboutClose(CloseState);
 
     void requestSpace(uint64_t taskSize, const char* errorMessage, CompletionHandler<void(Optional<IDBError>&&)>&&);
+    void waitForRequestSpaceCompletion(CompletionHandler<void(Optional<IDBError>&&)>&&);
     void updateSpaceUsedIfNeeded(uint64_t callbackIdentifier);
 
     Ref<IDBServer> m_server;
index e814fb1..daaac1e 100644 (file)
@@ -75,7 +75,7 @@ void UniqueIDBDatabaseConnection::abortTransactionWithoutCallback(UniqueIDBDatab
     if (!m_database)
         return;
     
-    m_database->abortTransaction(transaction, [this, protectedThis, transactionIdentifier](const IDBError&) {
+    m_database->abortTransaction(transaction, UniqueIDBDatabase::WaitForPendingTasks::No, [this, protectedThis, transactionIdentifier](const IDBError&) {
         ASSERT(m_transactionMap.contains(transactionIdentifier));
         m_transactionMap.remove(transactionIdentifier);
     });
index 39a011d..44f4382 100644 (file)
@@ -81,7 +81,7 @@ void UniqueIDBDatabaseTransaction::abort()
     auto database = m_databaseConnection->database();
     ASSERT(database);
 
-    database->abortTransaction(*this, [this, protectedThis](const IDBError& error) {
+    database->abortTransaction(*this, UniqueIDBDatabase::WaitForPendingTasks::Yes, [this, protectedThis](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::abort (callback)");
         m_databaseConnection->didAbortTransaction(*this, error);
     });
index 4bf3ad6..437d56a 100644 (file)
@@ -655,11 +655,8 @@ unsigned long long DatabaseTracker::usage(const SecurityOriginData& origin)
 {
     String originPath = this->originPath(origin);
     unsigned long long diskUsage = 0;
-    for (auto& fileName : FileSystem::listDirectory(originPath, "*.db"_s)) {
-        long long size;
-        FileSystem::getFileSize(fileName, size);
-        diskUsage += size;
-    }
+    for (auto& fileName : FileSystem::listDirectory(originPath, "*.db"_s))
+        diskUsage += SQLiteFileSystem::getDatabaseFileSize(fileName);
     return diskUsage;
 }
 
index b9c9443..c24d211 100644 (file)
@@ -100,8 +100,19 @@ bool SQLiteFileSystem::truncateDatabaseFile(sqlite3* database)
     
 long long SQLiteFileSystem::getDatabaseFileSize(const String& fileName)
 {        
-    long long size;
-    return FileSystem::getFileSize(fileName, size) ? size : 0;
+    long long fileSize = 0;
+    long long totalSize = 0;
+
+    if (FileSystem::getFileSize(fileName, fileSize))
+        totalSize += fileSize;
+
+    if (FileSystem::getFileSize(makeString(fileName, "-wal"_s), fileSize))
+        totalSize += fileSize;
+
+    if (FileSystem::getFileSize(makeString(fileName, "-shm"_s), fileSize))
+        totalSize += fileSize;
+
+    return totalSize;
 }
 
 Optional<WallTime> SQLiteFileSystem::databaseCreationTime(const String& fileName)
index e30a40a..3d34834 100644 (file)
@@ -58,6 +58,14 @@ void StorageQuotaManager::addUser(StorageQuotaUser& user)
     });
 }
 
+bool StorageQuotaManager::shouldAskForMoreSpace(uint64_t spaceIncrease) const
+{
+    if (!spaceIncrease)
+        return false;
+
+    return spaceUsage() + spaceIncrease > m_quota;
+}
+
 void StorageQuotaManager::requestSpace(uint64_t spaceIncrease, RequestCallback&& callback)
 {
     if (!m_pendingRequests.isEmpty() || !m_pendingInitializationUsers.isEmpty()) {
@@ -65,19 +73,18 @@ void StorageQuotaManager::requestSpace(uint64_t spaceIncrease, RequestCallback&&
         return;
     }
 
-    auto spaceUsage = this->spaceUsage();
-    if (spaceUsage + spaceIncrease > m_quota) {
+    if (shouldAskForMoreSpace(spaceIncrease)) {
         m_pendingRequests.append({ spaceIncrease, WTFMove(callback) });
-        askForMoreSpace(spaceUsage, spaceIncrease);
+        askForMoreSpace(spaceIncrease);
         return;
     }
     callback(Decision::Grant);
 }
 
-void StorageQuotaManager::askForMoreSpace(uint64_t spaceUsage, uint64_t spaceIncrease)
+void StorageQuotaManager::askForMoreSpace(uint64_t spaceIncrease)
 {
-    ASSERT(spaceUsage + spaceIncrease > m_quota);
-    m_spaceIncreaseRequester(m_quota, spaceUsage, spaceIncrease, [this, weakThis = makeWeakPtr(*this)](Optional<uint64_t> newQuota) {
+    ASSERT(shouldAskForMoreSpace(spaceIncrease));
+    m_spaceIncreaseRequester(m_quota, spaceUsage(), spaceIncrease, [this, weakThis = makeWeakPtr(*this)](Optional<uint64_t> newQuota) {
         if (!weakThis)
             return;
         processPendingRequests(newQuota);
@@ -93,18 +100,17 @@ void StorageQuotaManager::processPendingRequests(Optional<uint64_t> newQuota)
         m_quota = *newQuota;
 
     auto request = m_pendingRequests.takeFirst();
-    auto decision = m_quota >= (spaceUsage() + request.spaceIncrease) ? Decision::Grant : Decision::Deny;
+    auto decision = shouldAskForMoreSpace(request.spaceIncrease) ? Decision::Deny : Decision::Grant;
     request.callback(decision);
 
     while (!m_pendingRequests.isEmpty()) {
         auto& request = m_pendingRequests.first();
 
-        auto spaceUsage = this->spaceUsage();
-        if (m_quota < spaceUsage + request.spaceIncrease) {
+        if (shouldAskForMoreSpace(request.spaceIncrease)) {
             uint64_t spaceIncrease = 0;
             for (auto& request : m_pendingRequests)
                 spaceIncrease += request.spaceIncrease;
-            askForMoreSpace(spaceUsage, spaceIncrease);
+            askForMoreSpace(spaceIncrease);
             return;
         }
 
index f0968d1..0aab548 100644 (file)
@@ -64,7 +64,8 @@ public:
 
 private:
     uint64_t spaceUsage() const;
-    void askForMoreSpace(uint64_t spaceUsage, uint64_t spaceIncrease);
+    bool shouldAskForMoreSpace(uint64_t spaceIncrease) const;
+    void askForMoreSpace(uint64_t spaceIncrease);
     void processPendingRequests(Optional<uint64_t>);
 
     uint64_t m_quota { 0 };