Title: [250800] trunk
Revision
250800
Author
sihui_...@apple.com
Date
2019-10-07 15:36:47 -0700 (Mon, 07 Oct 2019)

Log Message

ASSERTION FAILED: m_transactionOperationsInProgressQueue.first() == &operation in IDBTransaction::operationCompletedOnClient
https://bugs.webkit.org/show_bug.cgi?id=202552

Reviewed by Alex Christensen.

Source/WebCore:

Dispatch task to database thread even if there is QuotaExceededError, to make sure request results are sent in
order.

Modified existing test to cover this: storage/indexeddb/storage-limit.html. Test would hit this assertion
without fix.

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::requestSpace):
(WebCore::IDBServer::UniqueIDBDatabase::waitForRequestSpaceCompletion):
(WebCore::IDBServer::UniqueIDBDatabase::createObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::createObjectStoreAfterQuotaCheck):
(WebCore::IDBServer::UniqueIDBDatabase::performCreateObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::deleteObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::renameObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::renameObjectStoreAfterQuotaCheck):
(WebCore::IDBServer::UniqueIDBDatabase::performRenameObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::clearObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::createIndex):
(WebCore::IDBServer::UniqueIDBDatabase::createIndexAfterQuotaCheck):
(WebCore::IDBServer::UniqueIDBDatabase::performCreateIndex):
(WebCore::IDBServer::UniqueIDBDatabase::deleteIndex):
(WebCore::IDBServer::UniqueIDBDatabase::renameIndex):
(WebCore::IDBServer::UniqueIDBDatabase::renameIndexAfterQuotaCheck):
(WebCore::IDBServer::UniqueIDBDatabase::performRenameIndex):
(WebCore::IDBServer::UniqueIDBDatabase::putOrAdd):
(WebCore::IDBServer::UniqueIDBDatabase::putOrAddAfterQuotaCheck):
(WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd):
(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):
(WebCore::IDBServer::UniqueIDBDatabase::abortTransaction):
* Modules/indexeddb/server/UniqueIDBDatabase.h:

LayoutTests:

* storage/indexeddb/resources/storage-limit.js:
(onOpenSuccess.request.onerror):
* storage/indexeddb/storage-limit-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (250799 => 250800)


--- trunk/LayoutTests/ChangeLog	2019-10-07 22:14:41 UTC (rev 250799)
+++ trunk/LayoutTests/ChangeLog	2019-10-07 22:36:47 UTC (rev 250800)
@@ -1,3 +1,14 @@
+2019-10-07  Sihui Liu  <sihui_...@apple.com>
+
+        ASSERTION FAILED: m_transactionOperationsInProgressQueue.first() == &operation in IDBTransaction::operationCompletedOnClient
+        https://bugs.webkit.org/show_bug.cgi?id=202552
+
+        Reviewed by Alex Christensen.
+
+        * storage/indexeddb/resources/storage-limit.js:
+        (onOpenSuccess.request.onerror):
+        * storage/indexeddb/storage-limit-expected.txt:
+
 2019-10-07  Ryosuke Niwa  <rn...@webkit.org>
 
         focus pseudo class should match a shadow host whose shadow tree contains the focused element

Modified: trunk/LayoutTests/storage/indexeddb/resources/storage-limit.js (250799 => 250800)


--- trunk/LayoutTests/storage/indexeddb/resources/storage-limit.js	2019-10-07 22:14:41 UTC (rev 250799)
+++ trunk/LayoutTests/storage/indexeddb/resources/storage-limit.js	2019-10-07 22:36:47 UTC (rev 250800)
@@ -23,8 +23,16 @@
     preamble(event);
     evalAndLog("db = event.target.result");
     evalAndLog("store = db.transaction('store', 'readwrite').objectStore('store')");
+
+    // Small add should succeed.
+    evalAndLog("addCount = 0");
+    for (var i = 1; i <= 10; i ++)
+        evalAndLog("store.add(new Uint8Array(1), " + i + ")._onsuccess_ = ()=> { ++addCount; }");
+
+	// Big add should fail.
     evalAndLog("request = store.add(new Uint8Array(" + (quota + 1) + "), 0)");
     request._onerror_ = function(event) {
+        shouldBe("addCount", "10");
         shouldBeTrue("'error' in request");
         shouldBe("request.error.code", "DOMException.QUOTA_EXCEEDED_ERR");
         shouldBeEqualToString("request.error.name", "QuotaExceededError");

Modified: trunk/LayoutTests/storage/indexeddb/storage-limit-expected.txt (250799 => 250800)


--- trunk/LayoutTests/storage/indexeddb/storage-limit-expected.txt	2019-10-07 22:14:41 UTC (rev 250799)
+++ trunk/LayoutTests/storage/indexeddb/storage-limit-expected.txt	2019-10-07 22:36:47 UTC (rev 250800)
@@ -15,7 +15,19 @@
 onOpenSuccess():
 db = event.target.result
 store = db.transaction('store', 'readwrite').objectStore('store')
+addCount = 0
+store.add(new Uint8Array(1), 1)._onsuccess_ = ()=> { ++addCount; }
+store.add(new Uint8Array(1), 2)._onsuccess_ = ()=> { ++addCount; }
+store.add(new Uint8Array(1), 3)._onsuccess_ = ()=> { ++addCount; }
+store.add(new Uint8Array(1), 4)._onsuccess_ = ()=> { ++addCount; }
+store.add(new Uint8Array(1), 5)._onsuccess_ = ()=> { ++addCount; }
+store.add(new Uint8Array(1), 6)._onsuccess_ = ()=> { ++addCount; }
+store.add(new Uint8Array(1), 7)._onsuccess_ = ()=> { ++addCount; }
+store.add(new Uint8Array(1), 8)._onsuccess_ = ()=> { ++addCount; }
+store.add(new Uint8Array(1), 9)._onsuccess_ = ()=> { ++addCount; }
+store.add(new Uint8Array(1), 10)._onsuccess_ = ()=> { ++addCount; }
 request = store.add(new Uint8Array(409601), 0)
+PASS addCount is 10
 PASS 'error' in request is true
 PASS request.error.code is DOMException.QUOTA_EXCEEDED_ERR
 PASS request.error.name is "QuotaExceededError"

Modified: trunk/Source/WebCore/ChangeLog (250799 => 250800)


--- trunk/Source/WebCore/ChangeLog	2019-10-07 22:14:41 UTC (rev 250799)
+++ trunk/Source/WebCore/ChangeLog	2019-10-07 22:36:47 UTC (rev 250800)
@@ -1,3 +1,47 @@
+2019-10-07  Sihui Liu  <sihui_...@apple.com>
+
+        ASSERTION FAILED: m_transactionOperationsInProgressQueue.first() == &operation in IDBTransaction::operationCompletedOnClient
+        https://bugs.webkit.org/show_bug.cgi?id=202552
+
+        Reviewed by Alex Christensen.
+
+        Dispatch task to database thread even if there is QuotaExceededError, to make sure request results are sent in 
+        order.
+
+        Modified existing test to cover this: storage/indexeddb/storage-limit.html. Test would hit this assertion 
+        without fix.
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::requestSpace):
+        (WebCore::IDBServer::UniqueIDBDatabase::waitForRequestSpaceCompletion):
+        (WebCore::IDBServer::UniqueIDBDatabase::createObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::createObjectStoreAfterQuotaCheck):
+        (WebCore::IDBServer::UniqueIDBDatabase::performCreateObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::deleteObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::renameObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::renameObjectStoreAfterQuotaCheck):
+        (WebCore::IDBServer::UniqueIDBDatabase::performRenameObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::clearObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::createIndex):
+        (WebCore::IDBServer::UniqueIDBDatabase::createIndexAfterQuotaCheck):
+        (WebCore::IDBServer::UniqueIDBDatabase::performCreateIndex):
+        (WebCore::IDBServer::UniqueIDBDatabase::deleteIndex):
+        (WebCore::IDBServer::UniqueIDBDatabase::renameIndex):
+        (WebCore::IDBServer::UniqueIDBDatabase::renameIndexAfterQuotaCheck):
+        (WebCore::IDBServer::UniqueIDBDatabase::performRenameIndex):
+        (WebCore::IDBServer::UniqueIDBDatabase::putOrAdd):
+        (WebCore::IDBServer::UniqueIDBDatabase::putOrAddAfterQuotaCheck):
+        (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd):
+        (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):
+        (WebCore::IDBServer::UniqueIDBDatabase::abortTransaction):
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+
 2019-10-07  Keith Rollin  <krol...@apple.com>
 
         Unreviewed, build fix after r250666. Fix 32- vs. 64-bit mismatch on

Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (250799 => 250800)


--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2019-10-07 22:14:41 UTC (rev 250799)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp	2019-10-07 22:36:47 UTC (rev 250800)
@@ -186,7 +186,7 @@
     return makeString("Failed to ", taskName, " in database because not enough space for domain");
 }
 
-void UniqueIDBDatabase::requestSpace(UniqueIDBDatabaseTransaction& transaction, uint64_t taskSize, const char* taskName, CompletionHandler<void(Optional<IDBError>&&)>&& callback)
+void UniqueIDBDatabase::requestSpace(UniqueIDBDatabaseTransaction& transaction, uint64_t taskSize, const char* taskName, CompletionHandler<void(IDBError&&)>&& callback)
 {
     m_server->requestSpace(m_identifier.origin(), taskSize, [weakThis = makeWeakPtr(this), this, weakTransaction = makeWeakPtr(transaction), taskName, callback = WTFMove(callback)](auto decision) mutable {
         if (!weakThis) {
@@ -209,12 +209,12 @@
             callback(IDBError { QuotaExceededError, quotaErrorMessageName(taskName) });
             return;
         case StorageQuotaManager::Decision::Grant:
-            callback({ });
+            callback(IDBError { });
         };
     });
 }
 
-void UniqueIDBDatabase::waitForRequestSpaceCompletion(UniqueIDBDatabaseTransaction& transaction, CompletionHandler<void(Optional<IDBError>&&)>&& callback)
+void UniqueIDBDatabase::waitForRequestSpaceCompletion(UniqueIDBDatabaseTransaction& transaction, CompletionHandler<void(IDBError&&)>&& callback)
 {
     requestSpace(transaction, 0, "", WTFMove(callback));
 }
@@ -838,28 +838,33 @@
 
     auto taskSize = defaultWriteOperationCost + estimateSize(info);
     requestSpace(transaction, taskSize, "createObjectStore", [this, taskSize, &transaction, info, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error));
+        if (!error.isNull() && *error.code() != QuotaExceededError) {
+            callback(WTFMove(error));
             return;
         }
-        this->createObjectStoreAfterQuotaCheck(taskSize, transaction, info, WTFMove(callback));
+        this->createObjectStoreAfterQuotaCheck(taskSize, transaction, info, WTFMove(callback), error);
     });
 }
 
-void UniqueIDBDatabase::createObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, const IDBObjectStoreInfo& info, ErrorCallback callback)
+void UniqueIDBDatabase::createObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, const IDBObjectStoreInfo& info, ErrorCallback callback, const IDBError& quotaError)
 {
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback), taskSize);
     if (!callbackID)
         return;
 
-    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateObjectStore, callbackID, transaction.info().identifier(), info));
+    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateObjectStore, callbackID, transaction.info().identifier(), info,  quotaError));
 }
 
-void UniqueIDBDatabase::performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info)
+void UniqueIDBDatabase::performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info, const IDBError& quotaError)
 {
     ASSERT(!isMainThread());
     LOG(IndexedDB, "(db) UniqueIDBDatabase::performCreateObjectStore");
 
+    if (!quotaError.isNull()) {
+        postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCreateObjectStore, callbackIdentifier, quotaError, info));
+        return;
+    }
+
     ASSERT(m_backingStore);
     m_backingStore->createObjectStore(transactionIdentifier, info);
 
@@ -883,9 +888,9 @@
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteObjectStore");
 
-    waitForRequestSpaceCompletion(transaction, [this, &transaction, objectStoreName, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error));
+    waitForRequestSpaceCompletion(transaction, [this, &transaction, objectStoreName, callback = WTFMove(callback)](auto&& error) mutable {
+        if (!error.isNull()) {
+            callback(WTFMove(error));
             return;
         }
         this->deleteObjectStoreAfterQuotaCheck(transaction, objectStoreName, WTFMove(callback));
@@ -937,38 +942,41 @@
 
     auto taskSize = defaultWriteOperationCost + newName.sizeInBytes();
     requestSpace(transaction, taskSize, "renameObjectStore", [this, taskSize, &transaction, objectStoreIdentifier, newName, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error));
+        if (!error.isNull() && *error.code() != QuotaExceededError) {
+            callback(WTFMove(error));
             return;
         }
-        this->renameObjectStoreAfterQuotaCheck(taskSize, transaction, objectStoreIdentifier, newName, WTFMove(callback));
+        this->renameObjectStoreAfterQuotaCheck(taskSize, transaction, objectStoreIdentifier, newName, WTFMove(callback), error);
     });
 }
 
-void UniqueIDBDatabase::renameObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, const String& newName, ErrorCallback callback)
+void UniqueIDBDatabase::renameObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, const String& newName, ErrorCallback callback, const IDBError& quotaError)
 {
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback), taskSize);
     if (!callbackID)
         return;
 
+    IDBError error = quotaError;
     auto* info = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
-    if (!info) {
-        performErrorCallback(callbackID, IDBError { UnknownError, "Attempt to rename non-existant object store"_s });
-        return;
-    }
+    if (!info)
+        error = IDBError { UnknownError, "Attempt to rename non-existant object store"_s };
 
-    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performRenameObjectStore, callbackID, transaction.info().identifier(), objectStoreIdentifier, newName));
+    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performRenameObjectStore, callbackID, transaction.info().identifier(), objectStoreIdentifier, newName, error));
 }
 
-void UniqueIDBDatabase::performRenameObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& newName)
+void UniqueIDBDatabase::performRenameObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& newName, const IDBError& error)
 {
     ASSERT(!isMainThread());
     LOG(IndexedDB, "(db) UniqueIDBDatabase::performRenameObjectStore");
 
+    if (!error.isNull()) {
+        postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformRenameObjectStore, callbackIdentifier, error, objectStoreIdentifier, newName));
+        return;
+    }
+
     ASSERT(m_backingStore);
     m_backingStore->renameObjectStore(transactionIdentifier, objectStoreIdentifier, newName);
 
-    IDBError error;
     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformRenameObjectStore, callbackIdentifier, error, objectStoreIdentifier, newName));
 }
 
@@ -988,9 +996,9 @@
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::clearObjectStore");
 
-    waitForRequestSpaceCompletion(transaction, [this, &transaction, objectStoreIdentifier, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error));
+    waitForRequestSpaceCompletion(transaction, [this, &transaction, objectStoreIdentifier, callback = WTFMove(callback)](auto&& error) mutable {
+        if (!error.isNull()) {
+            callback(WTFMove(error));
             return;
         }
         this->clearObjectStoreAfetQuotaCheck(transaction, objectStoreIdentifier, WTFMove(callback));
@@ -1032,27 +1040,32 @@
 
     auto taskSize = defaultWriteOperationCost + estimateSize(info);
     requestSpace(transaction, taskSize, "createIndex", [this, taskSize, &transaction, info, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error));
+        if (!error.isNull() && *error.code() != QuotaExceededError) {
+            callback(WTFMove(error));
             return;
         }
-        this->createIndexAfterQuotaCheck(taskSize, transaction, info, WTFMove(callback));
+        this->createIndexAfterQuotaCheck(taskSize, transaction, info, WTFMove(callback), error);
     });
 }
 
-void UniqueIDBDatabase::createIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, const IDBIndexInfo& info, ErrorCallback callback)
+void UniqueIDBDatabase::createIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, const IDBIndexInfo& info, ErrorCallback callback, const IDBError& quotaError)
 {
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback), taskSize);
     if (!callbackID)
         return;
-    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateIndex, callbackID, transaction.info().identifier(), info));
+    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateIndex, callbackID, transaction.info().identifier(), info, quotaError));
 }
 
-void UniqueIDBDatabase::performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& info)
+void UniqueIDBDatabase::performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& info, const IDBError& quotaError)
 {
     ASSERT(!isMainThread());
     LOG(IndexedDB, "(db) UniqueIDBDatabase::performCreateIndex");
 
+    if (!quotaError.isNull()) {
+        postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCreateIndex, callbackIdentifier, quotaError, info));
+        return;
+    }
+
     IDBError error;
     ASSERT(m_backingStore);
     if (!m_backingStore) {
@@ -1086,9 +1099,9 @@
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteIndex");
 
-    waitForRequestSpaceCompletion(transaction, [this, &transaction, objectStoreIdentifier, indexName, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error));
+    waitForRequestSpaceCompletion(transaction, [this, &transaction, objectStoreIdentifier, indexName, callback = WTFMove(callback)](auto&& error) mutable {
+        if (!error.isNull()) {
+            callback(WTFMove(error));
             return;
         }
         this->deleteIndexAfterQuotaCheck(transaction, objectStoreIdentifier, indexName, WTFMove(callback));
@@ -1149,44 +1162,45 @@
 
     auto taskSize = defaultWriteOperationCost + newName.sizeInBytes();
     requestSpace(transaction, taskSize, "renameIndex", [this, taskSize, &transaction, objectStoreIdentifier, indexIdentifier, newName, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error));
+        if (!error.isNull() && *error.code() != QuotaExceededError) {
+            callback(WTFMove(error));
             return;
         }
-        this->renameIndexAfterQuotaCheck(taskSize, transaction, objectStoreIdentifier, indexIdentifier, newName, WTFMove(callback));
+        this->renameIndexAfterQuotaCheck(taskSize, transaction, objectStoreIdentifier, indexIdentifier, newName, WTFMove(callback), error);
     });
 }
 
-void UniqueIDBDatabase::renameIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, ErrorCallback callback)
+void UniqueIDBDatabase::renameIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, ErrorCallback callback, const IDBError& quotaError)
 {
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback), taskSize);
     if (!callbackID)
         return;
 
+    IDBError error = quotaError;
     auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
-    if (!objectStoreInfo) {
-        performErrorCallback(callbackID, IDBError { UnknownError, "Attempt to rename index in non-existant object store"_s });
-        return;
-    }
+    if (!objectStoreInfo)
+        error = IDBError { UnknownError, "Attempt to rename index in non-existant object store"_s };
 
     auto* indexInfo = objectStoreInfo->infoForExistingIndex(indexIdentifier);
-    if (!indexInfo) {
-        performErrorCallback(callbackID, IDBError { UnknownError, "Attempt to rename non-existant index"_s });
-        return;
-    }
+    if (!indexInfo)
+        error = IDBError { UnknownError, "Attempt to rename non-existant index"_s };
 
-    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performRenameIndex, callbackID, transaction.info().identifier(), objectStoreIdentifier, indexIdentifier, newName));
+    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performRenameIndex, callbackID, transaction.info().identifier(), objectStoreIdentifier, indexIdentifier, newName, error));
 }
 
-void UniqueIDBDatabase::performRenameIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
+void UniqueIDBDatabase::performRenameIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, const IDBError& error)
 {
     ASSERT(!isMainThread());
     LOG(IndexedDB, "(db) UniqueIDBDatabase::performRenameIndex");
 
+    if (!error.isNull()) {
+        postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformRenameIndex, callbackIdentifier, error, objectStoreIdentifier, indexIdentifier, newName));
+        return;
+    }
+
     ASSERT(m_backingStore);
     m_backingStore->renameIndex(transactionIdentifier, objectStoreIdentifier, indexIdentifier, newName);
 
-    IDBError error;
     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformRenameIndex, callbackIdentifier, error, objectStoreIdentifier, indexIdentifier, newName));
 }
 
@@ -1215,23 +1229,23 @@
 
     auto taskSize = defaultWriteOperationCost + estimateSize(keyData) + estimateSize(value);
     requestSpace(transaction, taskSize, "putOrAdd", [this, taskSize, requestData, keyData, value, callback = WTFMove(callback), overwriteMode](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error), { });
+        if (!error.isNull() && *error.code() != QuotaExceededError) {
+            callback(WTFMove(error), { });
             return;
         }
-        this->putOrAddAfterQuotaCheck(taskSize, requestData, keyData, value, overwriteMode, WTFMove(callback));
+        this->putOrAddAfterQuotaCheck(taskSize, requestData, keyData, value, overwriteMode, WTFMove(callback), error);
     });
 }
 
-void UniqueIDBDatabase::putOrAddAfterQuotaCheck(uint64_t taskSize, const IDBRequestData& requestData, const IDBKeyData& keyData, const IDBValue& value, IndexedDB::ObjectStoreOverwriteMode overwriteMode, KeyDataCallback callback)
+void UniqueIDBDatabase::putOrAddAfterQuotaCheck(uint64_t taskSize, const IDBRequestData& requestData, const IDBKeyData& keyData, const IDBValue& value, IndexedDB::ObjectStoreOverwriteMode overwriteMode, KeyDataCallback callback, const IDBError& quotaError)
 {
     uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback), taskSize);
     if (!callbackID)
         return;
-    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, value, overwriteMode));
+    postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, value, overwriteMode, quotaError));
 }
 
-void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const IDBValue& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
+void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const IDBValue& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode, const IDBError& quotaError)
 {
     ASSERT(!isMainThread());
     LOG(IndexedDB, "(db) UniqueIDBDatabase::performPutOrAdd");
@@ -1242,6 +1256,11 @@
     IDBKeyData usedKey;
     IDBError error;
 
+    if (!quotaError.isNull()) {
+        postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, quotaError, usedKey));
+        return;
+    }
+
     if (!m_backingStore) {
         RELEASE_LOG_ERROR(IndexedDB, "%p - UniqueIDBDatabase::performPutOrAdd: m_backingStore is null", this);
         error = IDBError(InvalidStateError, "Backing store is invalid for call to put or add"_s);
@@ -1323,9 +1342,9 @@
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::getRecord");
 
-    waitForRequestSpaceCompletion(transaction, [this, requestData, getRecordData, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error), { });
+    waitForRequestSpaceCompletion(transaction, [this, requestData, getRecordData, callback = WTFMove(callback)](auto&& error) mutable {
+        if (!error.isNull()) {
+            callback(WTFMove(error), { });
             return;
         }
         this->getRecordAfterQuotaCheck(requestData, getRecordData, WTFMove(callback));
@@ -1349,9 +1368,9 @@
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::getAllRecords");
 
-    waitForRequestSpaceCompletion(transaction, [this, requestData, getAllRecordsData, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error), { });
+    waitForRequestSpaceCompletion(transaction, [this, requestData, getAllRecordsData, callback = WTFMove(callback)](auto&& error) mutable {
+        if (!error.isNull()) {
+            callback(WTFMove(error), { });
             return;
         }
         this->getAllRecordsAfterQuotaCheck(requestData, getAllRecordsData, WTFMove(callback));
@@ -1427,9 +1446,9 @@
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::getCount");
 
-    waitForRequestSpaceCompletion(transaction, [this, requestData, range, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error), { });
+    waitForRequestSpaceCompletion(transaction, [this, requestData, range, callback = WTFMove(callback)](auto&& error) mutable {
+        if (!error.isNull()) {
+            callback(WTFMove(error), { });
             return;
         }
         this->getCountAfterQuotaCheck(requestData, range, WTFMove(callback));
@@ -1471,9 +1490,9 @@
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteRecord");
 
-    waitForRequestSpaceCompletion(transaction, [this, requestData, keyRangeData, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error));
+    waitForRequestSpaceCompletion(transaction, [this, requestData, keyRangeData, callback = WTFMove(callback)](auto&& error) mutable {
+        if (!error.isNull()) {
+            callback(WTFMove(error));
             return;
         }
         this->deleteRecordAfterQuotaCheck(requestData, keyRangeData, WTFMove(callback));
@@ -1511,9 +1530,9 @@
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::openCursor");
 
-    waitForRequestSpaceCompletion(transaction, [this, requestData, info, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error), { });
+    waitForRequestSpaceCompletion(transaction, [this, requestData, info, callback = WTFMove(callback)](auto&& error) mutable {
+        if (!error.isNull()) {
+            callback(WTFMove(error), { });
             return;
         }
         this->openCursorAfterQuotaCheck(requestData, info, WTFMove(callback));
@@ -1552,9 +1571,9 @@
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::iterateCursor");
 
-    waitForRequestSpaceCompletion(transaction, [this, requestData, data, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error), { });
+    waitForRequestSpaceCompletion(transaction, [this, requestData, data, callback = WTFMove(callback)](auto&& error) mutable {
+        if (!error.isNull()) {
+            callback(WTFMove(error), { });
             return;
         }
         this->iterateCursorAfterQuotaCheck(requestData, data, WTFMove(callback));
@@ -1626,9 +1645,9 @@
 
     ASSERT(transaction.databaseConnection().database() == this);
 
-    waitForRequestSpaceCompletion(transaction, [this, &transaction, callback = WTFMove(callback)](auto error) mutable {
-        if (error) {
-            callback(WTFMove(*error));
+    waitForRequestSpaceCompletion(transaction, [this, &transaction, callback = WTFMove(callback)](auto&& error) mutable {
+        if (!error.isNull()) {
+            callback(WTFMove(error));
             return;
         }
         this->commitTransactionAfterQuotaCheck(transaction, WTFMove(callback));
@@ -1699,8 +1718,8 @@
 
     if (waitForPendingTasks == WaitForPendingTasks::Yes) {
         waitForRequestSpaceCompletion(transaction, [this, &transaction, callback = WTFMove(callback)](auto&& error) mutable {
-            if (error) {
-                callback(WTFMove(*error));
+            if (!error.isNull()) {
+                callback(WTFMove(error));
                 return;
             }
             this->abortTransaction(transaction, WaitForPendingTasks::No, WTFMove(callback));

Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (250799 => 250800)


--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h	2019-10-07 22:14:41 UTC (rev 250799)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h	2019-10-07 22:36:47 UTC (rev 250800)
@@ -141,11 +141,11 @@
 
     void scheduleShutdownForClose();
 
-    void createObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, const IDBObjectStoreInfo&, ErrorCallback);
-    void renameObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, const String& newName, ErrorCallback);
-    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 createObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, const IDBObjectStoreInfo&, ErrorCallback, const IDBError&);
+    void renameObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, const String& newName, ErrorCallback, const IDBError&);
+    void createIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, const IDBIndexInfo&, ErrorCallback, const IDBError&);
+    void renameIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, ErrorCallback, const IDBError&);
+    void putOrAddAfterQuotaCheck(uint64_t taskSize, const IDBRequestData&, const IDBKeyData&, const IDBValue&, IndexedDB::ObjectStoreOverwriteMode, KeyDataCallback, const IDBError&);
     void deleteRecordAfterQuotaCheck(const IDBRequestData&, const IDBKeyRangeData&, ErrorCallback);
 
     void deleteObjectStoreAfterQuotaCheck(UniqueIDBDatabaseTransaction&, const String& objectStoreName, ErrorCallback);
@@ -164,14 +164,14 @@
     void performCommitTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier);
     void performAbortTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier);
     void beginTransactionInBackingStore(const IDBTransactionInfo&);
-    void performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&);
+    void performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&, const IDBError&);
     void performDeleteObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier);
-    void performRenameObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& newName);
+    void performRenameObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& newName, const IDBError&);
     void performClearObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier);
-    void performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo&);
+    void performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo&, const IDBError&);
     void performDeleteIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier);
-    void performRenameIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName);
-    void performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const IDBValue&, IndexedDB::ObjectStoreOverwriteMode);
+    void performRenameIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, const IDBError&);
+    void performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const IDBValue&, IndexedDB::ObjectStoreOverwriteMode, const IDBError&);
     void performGetRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&, IDBGetRecordDataType);
     void performGetAllRecords(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData&);
     void performGetIndexRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&);
@@ -247,8 +247,8 @@
     void maybeFinishHardClose();
     bool isDoneWithHardClose();
 
-    void requestSpace(UniqueIDBDatabaseTransaction&, uint64_t taskSize, const char* errorMessage, CompletionHandler<void(Optional<IDBError>&&)>&&);
-    void waitForRequestSpaceCompletion(UniqueIDBDatabaseTransaction&, CompletionHandler<void(Optional<IDBError>&&)>&&);
+    void requestSpace(UniqueIDBDatabaseTransaction&, uint64_t taskSize, const char* errorMessage, CompletionHandler<void(IDBError&&)>&&);
+    void waitForRequestSpaceCompletion(UniqueIDBDatabaseTransaction&, CompletionHandler<void(IDBError&&)>&&);
     void updateSpaceUsedIfNeeded(Optional<uint64_t> optionalCallbackIdentifier = WTF::nullopt);
 
     Ref<IDBServer> m_server;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to