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:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@250800 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d78302a..12b6dd0 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2019-10-07 Sihui Liu <sihui_liu@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 <rniwa@webkit.org>
focus pseudo class should match a shadow host whose shadow tree contains the focused element
diff --git a/LayoutTests/storage/indexeddb/resources/storage-limit.js b/LayoutTests/storage/indexeddb/resources/storage-limit.js
index 81be6d2..f1a36fc 100644
--- a/LayoutTests/storage/indexeddb/resources/storage-limit.js
+++ b/LayoutTests/storage/indexeddb/resources/storage-limit.js
@@ -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");
diff --git a/LayoutTests/storage/indexeddb/storage-limit-expected.txt b/LayoutTests/storage/indexeddb/storage-limit-expected.txt
index a4cf6a9..9a74526 100644
--- a/LayoutTests/storage/indexeddb/storage-limit-expected.txt
+++ b/LayoutTests/storage/indexeddb/storage-limit-expected.txt
@@ -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"
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 66ae103..59cf253 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,47 @@
+2019-10-07 Sihui Liu <sihui_liu@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 <krollin@apple.com>
Unreviewed, build fix after r250666. Fix 32- vs. 64-bit mismatch on
diff --git a/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp b/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
index 806d0eb..c939a00 100644
--- a/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
+++ b/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
@@ -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));
diff --git a/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h b/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h
index 53b21df..141801d 100644
--- a/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h
+++ b/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h
@@ -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;