Title: [280053] trunk
Revision
280053
Author
[email protected]
Date
2021-07-19 16:09:48 -0700 (Mon, 19 Jul 2021)

Log Message

Implement IDBTransaction.commit()
https://bugs.webkit.org/show_bug.cgi?id=227815
<rdar://problem/80651270>

Reviewed by Brady Eidson.

LayoutTests/imported/w3c:

* web-platform-tests/IndexedDB/idb-explicit-commit-throw.any-expected.txt:
* web-platform-tests/IndexedDB/idb-explicit-commit-throw.any.worker-expected.txt:
* web-platform-tests/IndexedDB/idb-explicit-commit.any-expected.txt: Some test is timed out as our backend does
not support running multiple transactions simultaneously now.
* web-platform-tests/IndexedDB/idb-explicit-commit.any.worker-expected.txt: Ditto.
* web-platform-tests/IndexedDB/idlharness.any-expected.txt:
* web-platform-tests/IndexedDB/idlharness.any.worker-expected.txt:

Source/WebCore:

Spec: https://www.w3.org/TR/IndexedDB/#dom-idbtransaction-commit

Commit request for IDBTransaction is created automatically after all its requests are completed and success
events of those requests are fired. IDBTransaction.commit() lets client create commit request, without waiting
for the result of requests, so the commit can happen sooner.

In our implementation, if pending requests before the commit request are completed successfully, commit request
will be executed directly in the backend and dose not affect by things happening in request event handler. If
some pending request before the commit request has error, the commit request will be treated as abort request,
as commit() means no client operation, including error handling, should happen after it.

Rebaselined existing tests.

* Modules/indexeddb/IDBDatabase.cpp:
(WebCore::IDBDatabase::didStartTransaction):
* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::dispatchEvent):
(WebCore::IDBRequest::willAbortTransactionAfterDispatchingEvent const):
* Modules/indexeddb/IDBRequest.h:
* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::abortDueToFailedRequest):
(WebCore::IDBTransaction::abort):
(WebCore::IDBTransaction::abortInternal):
(WebCore::IDBTransaction::stop):
(WebCore::IDBTransaction::handleOperationsCompletedOnServer):
(WebCore::IDBTransaction::commit): If commit() is called in event handler for error event, and the error is
handled before the call, we will create a commit requet. Otherwise, it is ignored as transaction will abort
due to the error.
(WebCore::IDBTransaction::commitInternal):
(WebCore::IDBTransaction::commitOnServer):
(WebCore::IDBTransaction::didCommit): didCommit used to be called after all requests are done and events are
fired. As commit request can now be handled and replied before other requests, we need to make sure complete
event of transaction is fired after success event of requests, by tracking completion of the last request before
commit request.
(WebCore::IDBTransaction::operationCompletedOnClient):
(WebCore::IDBTransaction::autoCommit):
(WebCore::IDBTransaction::internalAbort): Deleted.
* Modules/indexeddb/IDBTransaction.h:
* Modules/indexeddb/IDBTransaction.idl:
* Modules/indexeddb/client/IDBConnectionProxy.cpp:
(WebCore::IDBClient::IDBConnectionProxy::commitTransaction):
* Modules/indexeddb/client/IDBConnectionProxy.h:
* Modules/indexeddb/client/IDBConnectionToServer.cpp:
(WebCore::IDBClient::IDBConnectionToServer::commitTransaction):
* Modules/indexeddb/client/IDBConnectionToServer.h:
* Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::commitTransaction):
* Modules/indexeddb/server/IDBServer.h:
* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::commit):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::createObjectStore):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteObjectStore):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::renameObjectStore):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::clearObjectStore):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::createIndex):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteIndex):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::renameIndex):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::putOrAdd):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::getRecord):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::getAllRecords):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::getCount):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteRecord):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::openCursor):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::iterateCursor):
* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:
* loader/EmptyClients.cpp:

Source/WebKit:

* NetworkProcess/IndexedDB/WebIDBServer.cpp:
(WebKit::WebIDBServer::commitTransaction):
* NetworkProcess/IndexedDB/WebIDBServer.h:
* NetworkProcess/IndexedDB/WebIDBServer.messages.in:
* WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
(WebKit::WebIDBConnectionToServer::commitTransaction):
* WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h:

Source/WebKitLegacy:

* Storage/InProcessIDBServer.cpp:
(InProcessIDBServer::commitTransaction):
* Storage/InProcessIDBServer.h:

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (280052 => 280053)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-07-19 23:09:48 UTC (rev 280053)
@@ -1,3 +1,19 @@
+2021-07-19  Sihui Liu  <[email protected]>
+
+        Implement IDBTransaction.commit()
+        https://bugs.webkit.org/show_bug.cgi?id=227815
+        <rdar://problem/80651270>
+
+        Reviewed by Brady Eidson.
+
+        * web-platform-tests/IndexedDB/idb-explicit-commit-throw.any-expected.txt:
+        * web-platform-tests/IndexedDB/idb-explicit-commit-throw.any.worker-expected.txt:
+        * web-platform-tests/IndexedDB/idb-explicit-commit.any-expected.txt: Some test is timed out as our backend does
+        not support running multiple transactions simultaneously now.
+        * web-platform-tests/IndexedDB/idb-explicit-commit.any.worker-expected.txt: Ditto.
+        * web-platform-tests/IndexedDB/idlharness.any-expected.txt:
+        * web-platform-tests/IndexedDB/idlharness.any.worker-expected.txt:
+
 2021-07-19  Chris Dumez  <[email protected]>
 
         HTMLImageElement.decoding should reflect the decoding content attribute, limited to only known values

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit-throw.any-expected.txt (280052 => 280053)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit-throw.any-expected.txt	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit-throw.any-expected.txt	2021-07-19 23:09:48 UTC (rev 280053)
@@ -1,3 +1,3 @@
 
-FAIL Any errors in callbacks that run after an explicit commit will not stop the commit from being processed. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
+PASS Any errors in callbacks that run after an explicit commit will not stop the commit from being processed.
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit-throw.any.worker-expected.txt (280052 => 280053)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit-throw.any.worker-expected.txt	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit-throw.any.worker-expected.txt	2021-07-19 23:09:48 UTC (rev 280053)
@@ -1,3 +1,3 @@
 
-FAIL Any errors in callbacks that run after an explicit commit will not stop the commit from being processed. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
+PASS Any errors in callbacks that run after an explicit commit will not stop the commit from being processed.
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit.any-expected.txt (280052 => 280053)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit.any-expected.txt	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit.any-expected.txt	2021-07-19 23:09:48 UTC (rev 280053)
@@ -1,14 +1,16 @@
 
-FAIL Explicitly committed data can be read back out. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL commit() on a version change transaction does not cause errors. txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)
-FAIL A committed transaction becomes inactive immediately. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL A committed transaction is inactive in future request callbacks. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL Puts issued after commit are not fulfilled. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL Calling commit on an aborted transaction throws. assert_throws_dom: The transaction should have been aborted. function "() => { txn.commit(); }" threw object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-FAIL Calling commit on a committed transaction throws. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL Calling abort on a committed transaction throws and does not prevent persisting the data. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL Calling txn.commit() when txn is inactive should throw. assert_throws_dom: The transaction should be inactive so calling commit should throw. function "() => { txn.commit(); }" threw object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-FAIL Transactions with same scope should stay in program order, even if one calls commit. promise_test: Unhandled rejection with value: object "TypeError: txn2.commit is not a function. (In 'txn2.commit()', 'txn2.commit' is undefined)"
-FAIL Transactions that explicitly commit and have errors should abort. promise_test: Unhandled rejection with value: object "TypeError: txn1.commit is not a function. (In 'txn1.commit()', 'txn1.commit' is undefined)"
-FAIL Transactions that handle all errors properly should behave as expected when an explicit commit is called in an onerror handler. promise_test: Unhandled rejection with value: object "TypeError: txn1.commit is not a function. (In 'txn1.commit()', 'txn1.commit' is undefined)"
+Harness Error (TIMEOUT), message = null
 
+PASS Explicitly committed data can be read back out.
+PASS commit() on a version change transaction does not cause errors.
+PASS A committed transaction becomes inactive immediately.
+PASS A committed transaction is inactive in future request callbacks.
+PASS Puts issued after commit are not fulfilled.
+PASS Calling commit on an aborted transaction throws.
+PASS Calling commit on a committed transaction throws.
+PASS Calling abort on a committed transaction throws and does not prevent persisting the data.
+PASS Calling txn.commit() when txn is inactive should throw.
+TIMEOUT Transactions with same scope should stay in program order, even if one calls commit. Test timed out
+NOTRUN Transactions that explicitly commit and have errors should abort.
+NOTRUN Transactions that handle all errors properly should behave as expected when an explicit commit is called in an onerror handler.
+

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit.any.worker-expected.txt (280052 => 280053)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit.any.worker-expected.txt	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idb-explicit-commit.any.worker-expected.txt	2021-07-19 23:09:48 UTC (rev 280053)
@@ -1,14 +1,16 @@
 
-FAIL Explicitly committed data can be read back out. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL commit() on a version change transaction does not cause errors. txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)
-FAIL A committed transaction becomes inactive immediately. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL A committed transaction is inactive in future request callbacks. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL Puts issued after commit are not fulfilled. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL Calling commit on an aborted transaction throws. assert_throws_dom: The transaction should have been aborted. function "() => { txn.commit(); }" threw object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-FAIL Calling commit on a committed transaction throws. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL Calling abort on a committed transaction throws and does not prevent persisting the data. promise_test: Unhandled rejection with value: object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)"
-FAIL Calling txn.commit() when txn is inactive should throw. assert_throws_dom: The transaction should be inactive so calling commit should throw. function "() => { txn.commit(); }" threw object "TypeError: txn.commit is not a function. (In 'txn.commit()', 'txn.commit' is undefined)" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-FAIL Transactions with same scope should stay in program order, even if one calls commit. promise_test: Unhandled rejection with value: object "TypeError: txn2.commit is not a function. (In 'txn2.commit()', 'txn2.commit' is undefined)"
-FAIL Transactions that explicitly commit and have errors should abort. promise_test: Unhandled rejection with value: object "TypeError: txn1.commit is not a function. (In 'txn1.commit()', 'txn1.commit' is undefined)"
-FAIL Transactions that handle all errors properly should behave as expected when an explicit commit is called in an onerror handler. promise_test: Unhandled rejection with value: object "TypeError: txn1.commit is not a function. (In 'txn1.commit()', 'txn1.commit' is undefined)"
+Harness Error (TIMEOUT), message = null
 
+PASS Explicitly committed data can be read back out.
+PASS commit() on a version change transaction does not cause errors.
+PASS A committed transaction becomes inactive immediately.
+PASS A committed transaction is inactive in future request callbacks.
+PASS Puts issued after commit are not fulfilled.
+PASS Calling commit on an aborted transaction throws.
+PASS Calling commit on a committed transaction throws.
+PASS Calling abort on a committed transaction throws and does not prevent persisting the data.
+PASS Calling txn.commit() when txn is inactive should throw.
+TIMEOUT Transactions with same scope should stay in program order, even if one calls commit. Test timed out
+NOTRUN Transactions that explicitly commit and have errors should abort.
+NOTRUN Transactions that handle all errors properly should behave as expected when an explicit commit is called in an onerror handler.
+

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idlharness.any-expected.txt (280052 => 280053)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idlharness.any-expected.txt	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idlharness.any-expected.txt	2021-07-19 23:09:48 UTC (rev 280053)
@@ -189,7 +189,7 @@
 PASS IDBTransaction interface: attribute db
 PASS IDBTransaction interface: attribute error
 PASS IDBTransaction interface: operation objectStore(DOMString)
-FAIL IDBTransaction interface: operation commit() assert_own_property: interface prototype object missing non-static operation expected property "commit" missing
+PASS IDBTransaction interface: operation commit()
 PASS IDBTransaction interface: operation abort()
 PASS IDBTransaction interface: attribute onabort
 PASS IDBTransaction interface: attribute oncomplete

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idlharness.any.worker-expected.txt (280052 => 280053)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idlharness.any.worker-expected.txt	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/idlharness.any.worker-expected.txt	2021-07-19 23:09:48 UTC (rev 280053)
@@ -189,7 +189,7 @@
 PASS IDBTransaction interface: attribute db
 PASS IDBTransaction interface: attribute error
 PASS IDBTransaction interface: operation objectStore(DOMString)
-FAIL IDBTransaction interface: operation commit() assert_own_property: interface prototype object missing non-static operation expected property "commit" missing
+PASS IDBTransaction interface: operation commit()
 PASS IDBTransaction interface: operation abort()
 PASS IDBTransaction interface: attribute onabort
 PASS IDBTransaction interface: attribute oncomplete

Modified: trunk/Source/WebCore/ChangeLog (280052 => 280053)


--- trunk/Source/WebCore/ChangeLog	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/ChangeLog	2021-07-19 23:09:48 UTC (rev 280053)
@@ -1,3 +1,79 @@
+2021-07-19  Sihui Liu  <[email protected]>
+
+        Implement IDBTransaction.commit()
+        https://bugs.webkit.org/show_bug.cgi?id=227815
+        <rdar://problem/80651270>
+
+        Reviewed by Brady Eidson.
+
+        Spec: https://www.w3.org/TR/IndexedDB/#dom-idbtransaction-commit
+
+        Commit request for IDBTransaction is created automatically after all its requests are completed and success 
+        events of those requests are fired. IDBTransaction.commit() lets client create commit request, without waiting
+        for the result of requests, so the commit can happen sooner. 
+
+        In our implementation, if pending requests before the commit request are completed successfully, commit request 
+        will be executed directly in the backend and dose not affect by things happening in request event handler. If 
+        some pending request before the commit request has error, the commit request will be treated as abort request, 
+        as commit() means no client operation, including error handling, should happen after it.
+
+        Rebaselined existing tests.
+
+        * Modules/indexeddb/IDBDatabase.cpp:
+        (WebCore::IDBDatabase::didStartTransaction):
+        * Modules/indexeddb/IDBRequest.cpp:
+        (WebCore::IDBRequest::dispatchEvent):
+        (WebCore::IDBRequest::willAbortTransactionAfterDispatchingEvent const): 
+        * Modules/indexeddb/IDBRequest.h:
+        * Modules/indexeddb/IDBTransaction.cpp:
+        (WebCore::IDBTransaction::abortDueToFailedRequest):
+        (WebCore::IDBTransaction::abort):
+        (WebCore::IDBTransaction::abortInternal):
+        (WebCore::IDBTransaction::stop):
+        (WebCore::IDBTransaction::handleOperationsCompletedOnServer):
+        (WebCore::IDBTransaction::commit): If commit() is called in event handler for error event, and the error is 
+        handled before the call, we will create a commit requet. Otherwise, it is ignored as transaction will abort
+        due to the error.
+        (WebCore::IDBTransaction::commitInternal):
+        (WebCore::IDBTransaction::commitOnServer):
+        (WebCore::IDBTransaction::didCommit): didCommit used to be called after all requests are done and events are 
+        fired. As commit request can now be handled and replied before other requests, we need to make sure complete 
+        event of transaction is fired after success event of requests, by tracking completion of the last request before 
+        commit request.
+        (WebCore::IDBTransaction::operationCompletedOnClient):
+        (WebCore::IDBTransaction::autoCommit):
+        (WebCore::IDBTransaction::internalAbort): Deleted.
+        * Modules/indexeddb/IDBTransaction.h:
+        * Modules/indexeddb/IDBTransaction.idl:
+        * Modules/indexeddb/client/IDBConnectionProxy.cpp:
+        (WebCore::IDBClient::IDBConnectionProxy::commitTransaction):
+        * Modules/indexeddb/client/IDBConnectionProxy.h:
+        * Modules/indexeddb/client/IDBConnectionToServer.cpp:
+        (WebCore::IDBClient::IDBConnectionToServer::commitTransaction):
+        * Modules/indexeddb/client/IDBConnectionToServer.h:
+        * Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::commitTransaction):
+        * Modules/indexeddb/server/IDBServer.h:
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::commit):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::createObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::renameObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::clearObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::createIndex):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteIndex):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::renameIndex):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::putOrAdd):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::getRecord):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::getAllRecords):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::getCount):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteRecord):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::openCursor):
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::iterateCursor):
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:
+        * loader/EmptyClients.cpp:
+
 2021-07-19  Tim Nguyen  <[email protected]>
 
         Port <dialog> close event to modern event handling code

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -356,8 +356,9 @@
     ASSERT(!m_versionChangeTransaction);
     ASSERT(canCurrentThreadAccessThreadLocalData(originThread()));
 
-    // It is possible for the client to have aborted a transaction before the server replies back that it has started.
-    if (m_abortingTransactions.contains(transaction.info().identifier()))
+    // It is possible for the client to have aborted or committed a transaction
+    // before the server replies back that it has started.
+    if (m_abortingTransactions.contains(transaction.info().identifier()) || m_committingTransactions.contains(transaction.info().identifier()))
         return;
 
     m_activeTransactions.set(transaction.info().identifier(), &transaction);

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -296,7 +296,7 @@
     ASSERT(!isContextStopped());
 
     auto protectedThis = makeRef(*this);
-    m_dispatchingEvent = true;
+    m_eventBeingDispatched = &event;
 
     if (event.type() != eventNames().blockedEvent)
         m_readyState = ReadyState::Done;
@@ -320,7 +320,7 @@
     if (!m_hasPendingActivity)
         m_hasPendingActivity = isOpenDBRequest() && (event.type() == eventNames().upgradeneededEvent || event.type() == eventNames().blockedEvent);
 
-    m_dispatchingEvent = false;
+    m_eventBeingDispatched = nullptr;
     if (!m_transaction)
         return;
 
@@ -344,7 +344,7 @@
 
     ASSERT(canCurrentThreadAccessThreadLocalData(originThread()));
 
-    if (m_dispatchingEvent) {
+    if (m_eventBeingDispatched) {
         ASSERT(!m_hasUncaughtException);
         m_hasUncaughtException = true;
         return;
@@ -567,5 +567,15 @@
     );
 }
 
+bool IDBRequest::willAbortTransactionAfterDispatchingEvent() const
+{
+    if (!m_eventBeingDispatched)
+        return false;
 
+    if (m_hasUncaughtException)
+        return true;
+
+    return !m_eventBeingDispatched->defaultPrevented() && m_eventBeingDispatched->type() == eventNames().errorEvent;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h	2021-07-19 23:09:48 UTC (rev 280053)
@@ -125,6 +125,7 @@
     IndexedDB::RequestType requestType() const { return m_requestType; }
 
     void setTransactionOperationID(uint64_t transactionOperationID) { m_currentTransactionOperationID = transactionOperationID; }
+    bool willAbortTransactionAfterDispatchingEvent() const;
 
 protected:
     IDBRequest(ScriptExecutionContext&, IDBClient::IDBConnectionProxy&, IndexedDB::RequestType);
@@ -197,8 +198,8 @@
 
     bool m_shouldExposeTransactionToDOM { true };
     bool m_hasPendingActivity { true };
-    bool m_dispatchingEvent { false };
     bool m_hasUncaughtException { false };
+    RefPtr<Event> m_eventBeingDispatched;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -192,7 +192,7 @@
         return;
 
     m_domError = &error;
-    internalAbort();
+    abortInternal();
 }
 
 void IDBTransaction::transitionedToFinishing(IndexedDB::TransactionState state)
@@ -212,14 +212,14 @@
     if (isFinishedOrFinishing())
         return Exception { InvalidStateError, "Failed to execute 'abort' on 'IDBTransaction': The transaction is inactive or finished."_s };
 
-    internalAbort();
+    abortInternal();
 
     return { };
 }
 
-void IDBTransaction::internalAbort()
+void IDBTransaction::abortInternal()
 {
-    LOG(IndexedDB, "IDBTransaction::internalAbort");
+    LOG(IndexedDB, "IDBTransaction::abortInternal");
     ASSERT(canCurrentThreadAccessThreadLocalData(m_database->originThread()));
     ASSERT(!isFinishedOrFinishing());
 
@@ -349,7 +349,7 @@
     if (isFinishedOrFinishing())
         return;
 
-    internalAbort();
+    abortInternal();
 }
 
 bool IDBTransaction::isActive() const
@@ -456,10 +456,26 @@
     handleOperationsCompletedOnServer();
 }
 
-void IDBTransaction::commit()
+ExceptionOr<void> IDBTransaction::commit()
 {
     LOG(IndexedDB, "IDBTransaction::commit");
     ASSERT(canCurrentThreadAccessThreadLocalData(m_database->originThread()));
+
+    if (!isActive())
+        return Exception { InvalidStateError, "Failed to execute 'commit' on 'IDBTransaction': The transaction is inactive."_s };
+
+    if (m_currentlyCompletingRequest && m_currentlyCompletingRequest->willAbortTransactionAfterDispatchingEvent())
+        return { };
+
+    commitInternal();
+
+    return { };
+}
+
+void IDBTransaction::commitInternal()
+{
+    LOG(IndexedDB, "IDBTransaction::commitInternal");
+    ASSERT(canCurrentThreadAccessThreadLocalData(m_database->originThread()));
     ASSERT(!isFinishedOrFinishing());
 
     transitionedToFinishing(IndexedDB::TransactionState::Committing);
@@ -466,21 +482,28 @@
     m_database->willCommitTransaction(*this);
 
     LOG(IndexedDBOperations, "IDB commit operation: Transaction %s", info().identifier().loggingString().utf8().data());
-    scheduleOperation(IDBClient::TransactionOperationImpl::create(*this, nullptr, [protectedThis = makeRef(*this)] (auto& operation) {
-        protectedThis->commitOnServer(operation);
+
+    auto pendingRequestCount = std::count_if(m_openRequests.begin(), m_openRequests.end(), [](auto& request) {
+        return !request->isDone();
+    });
+
+    scheduleOperation(IDBClient::TransactionOperationImpl::create(*this, nullptr, [protectedThis = Ref { *this }, pendingRequestCount] (auto& operation) {
+        protectedThis->commitOnServer(operation, pendingRequestCount);
     }));
 }
 
-void IDBTransaction::commitOnServer(IDBClient::TransactionOperation& operation)
+void IDBTransaction::commitOnServer(IDBClient::TransactionOperation& operation, uint64_t pendingRequestCount)
 {
     LOG(IndexedDB, "IDBTransaction::commitOnServer");
     ASSERT(canCurrentThreadAccessThreadLocalData(m_database->originThread()));
 
-    m_database->connectionProxy().commitTransaction(*this);
+    m_database->connectionProxy().commitTransaction(*this, pendingRequestCount);
 
     ASSERT(!m_transactionOperationsInProgressQueue.isEmpty());
     ASSERT(m_transactionOperationsInProgressQueue.last() == &operation);
     m_transactionOperationsInProgressQueue.removeLast();
+    if (!m_transactionOperationsInProgressQueue.isEmpty())
+        m_lastTransactionOperationBeforeCommit = m_transactionOperationsInProgressQueue.last()->identifier();
 
     ASSERT(m_transactionOperationMap.contains(operation.identifier()));
     m_transactionOperationMap.remove(operation.identifier());
@@ -551,6 +574,12 @@
     ASSERT(canCurrentThreadAccessThreadLocalData(m_database->originThread()));
     ASSERT(m_state == IndexedDB::TransactionState::Committing);
 
+    // Delay commit until last request is completed.
+    if (m_lastTransactionOperationBeforeCommit && m_transactionOperationMap.contains(*m_lastTransactionOperationBeforeCommit)) {
+        m_commitResult = error;
+        return;
+    }
+
     if (error.isNull()) {
         m_database->didCommitTransaction(*this);
         fireOnComplete();
@@ -1387,6 +1416,11 @@
     m_transactionOperationMap.remove(operation.identifier());
     m_transactionOperationsInProgressQueue.removeFirst();
 
+    if (m_commitResult && operation.identifier() == *m_lastTransactionOperationBeforeCommit) {
+        didCommit(*m_commitResult);
+        return;
+    }
+
     if (m_transactionOperationsInProgressQueue.isEmpty())
         handlePendingOperations();
 
@@ -1508,7 +1542,7 @@
         return;
     ASSERT(!m_currentlyCompletingRequest);
 
-    commit();
+    commitInternal();
 }
 
 uint64_t IDBTransaction::generateOperationID()

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h	2021-07-19 23:09:48 UTC (rev 280053)
@@ -81,6 +81,7 @@
     DOMException* error() const;
     ExceptionOr<Ref<IDBObjectStore>> objectStore(const String& name);
     ExceptionOr<void> abort();
+    ExceptionOr<void> commit();
 
     EventTargetInterface eventTargetInterface() const final { return IDBTransactionEventTargetInterfaceType; }
     ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
@@ -162,9 +163,8 @@
     const char* activeDOMObjectName() const final;
     bool virtualHasPendingActivity() const final;
 
-    void commit();
-
-    void internalAbort();
+    void commitInternal();
+    void abortInternal();
     void notifyDidAbort(const IDBError&);
     void finishAbortOrCommit();
     void abortInProgressOperations(const IDBError&);
@@ -181,7 +181,7 @@
 
     Ref<IDBRequest> requestIndexRecord(JSC::JSGlobalObject&, IDBIndex&, IndexedDB::IndexRecordType, const IDBKeyRangeData&);
 
-    void commitOnServer(IDBClient::TransactionOperation&);
+    void commitOnServer(IDBClient::TransactionOperation&, uint64_t pendingRequestCount);
     void abortOnServerAndCancelRequests(IDBClient::TransactionOperation&);
 
     void createObjectStoreOnServer(IDBClient::TransactionOperation&, const IDBObjectStoreInfo&);
@@ -252,7 +252,6 @@
     Deque<RefPtr<IDBClient::TransactionOperation>> m_abortQueue;
     Event* m_abortOrCommitEvent;
     HashMap<RefPtr<IDBClient::TransactionOperation>, IDBResultData> m_transactionOperationResultMap;
-
     HashMap<IDBResourceIdentifier, RefPtr<IDBClient::TransactionOperation>> m_transactionOperationMap;
 
     mutable Lock m_referencedObjectStoreLock;
@@ -266,6 +265,8 @@
     bool m_didDispatchAbortOrCommit { false };
 
     uint64_t m_lastWriteOperationID { 0 };
+    std::optional<IDBResourceIdentifier> m_lastTransactionOperationBeforeCommit;
+    std::optional<IDBError> m_commitResult;
 };
 
 class TransactionActivator {

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.idl (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.idl	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.idl	2021-07-19 23:09:48 UTC (rev 280053)
@@ -38,9 +38,8 @@
     readonly attribute DOMException? error;
 
     IDBObjectStore objectStore(DOMString name);
-    // FIXME: Implement 'commit'.
-    // undefined commit();
     undefined abort();
+    undefined commit();
 
     // Event handlers:
     attribute EventHandler onabort;

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -345,7 +345,7 @@
     transaction->performCallbackOnOriginThread(*transaction, &IDBTransaction::didStart, error);
 }
 
-void IDBConnectionProxy::commitTransaction(IDBTransaction& transaction)
+void IDBConnectionProxy::commitTransaction(IDBTransaction& transaction, uint64_t pendingRequestCount)
 {
     {
         Locker locker { m_transactionMapLock };
@@ -353,7 +353,7 @@
         m_committingTransactions.set(transaction.info().identifier(), &transaction);
     }
 
-    callConnectionOnMainThread(&IDBConnectionToServer::commitTransaction, transaction.info().identifier());
+    callConnectionOnMainThread(&IDBConnectionToServer::commitTransaction, transaction.info().identifier(), pendingRequestCount);
 }
 
 void IDBConnectionProxy::didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h	2021-07-19 23:09:48 UTC (rev 280053)
@@ -91,7 +91,7 @@
     void openDBRequestCancelled(const IDBRequestData&);
 
     void establishTransaction(IDBTransaction&);
-    void commitTransaction(IDBTransaction&);
+    void commitTransaction(IDBTransaction&, uint64_t pendingRequestCount);
     void abortTransaction(IDBTransaction&);
 
     void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -356,13 +356,13 @@
         m_delegate->establishTransaction(databaseConnectionIdentifier, info);
 }
 
-void IDBConnectionToServer::commitTransaction(const IDBResourceIdentifier& transactionIdentifier)
+void IDBConnectionToServer::commitTransaction(const IDBResourceIdentifier& transactionIdentifier, uint64_t pendingRequestCount)
 {
     LOG(IndexedDB, "IDBConnectionToServer::commitTransaction");
     ASSERT(isMainThread());
 
     if (m_serverConnectionIsValid)
-        m_delegate->commitTransaction(transactionIdentifier);
+        m_delegate->commitTransaction(transactionIdentifier, pendingRequestCount);
     else {
         callOnMainThread([this, protectedThis = makeRef(*this), transactionIdentifier] {
             didCommitTransaction(transactionIdentifier, IDBError::serverConnectionLostError());

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h	2021-07-19 23:09:48 UTC (rev 280053)
@@ -108,7 +108,7 @@
     void iterateCursor(const IDBRequestData&, const IDBIterateCursorData&);
     WEBCORE_EXPORT void didIterateCursor(const IDBResultData&);
 
-    void commitTransaction(const IDBResourceIdentifier& transactionIdentifier);
+    void commitTransaction(const IDBResourceIdentifier& transactionIdentifier, uint64_t pendingRequestCount);
     WEBCORE_EXPORT void didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
 
     void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier&);

Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h	2021-07-19 23:09:48 UTC (rev 280053)
@@ -62,7 +62,7 @@
     virtual void deleteDatabase(const IDBRequestData&) = 0;
     virtual void openDatabase(const IDBRequestData&) = 0;
     virtual void abortTransaction(const IDBResourceIdentifier&) = 0;
-    virtual void commitTransaction(const IDBResourceIdentifier&) = 0;
+    virtual void commitTransaction(const IDBResourceIdentifier&, uint64_t pendingRequestCount) = 0;
     virtual void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier&) = 0;
     virtual void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&) = 0;
     virtual void deleteObjectStore(const IDBRequestData&, const String& objectStoreName) = 0;

Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -408,7 +408,7 @@
         m_uniqueIDBDatabaseMap.remove(database->identifier());
 }
 
-void IDBServer::commitTransaction(const IDBResourceIdentifier& transactionIdentifier)
+void IDBServer::commitTransaction(const IDBResourceIdentifier& transactionIdentifier, uint64_t pendingRequestCount)
 {
     LOG(IndexedDB, "IDBServer::commitTransaction");
     ASSERT(!isMainThread());
@@ -421,7 +421,7 @@
         return;
     }
 
-    transaction->commit();
+    transaction->commit(pendingRequestCount);
 }
 
 void IDBServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)

Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h	2021-07-19 23:09:48 UTC (rev 280053)
@@ -62,7 +62,7 @@
     WEBCORE_EXPORT void openDatabase(const IDBRequestData&);
     WEBCORE_EXPORT void deleteDatabase(const IDBRequestData&);
     WEBCORE_EXPORT void abortTransaction(const IDBResourceIdentifier&);
-    WEBCORE_EXPORT void commitTransaction(const IDBResourceIdentifier&);
+    WEBCORE_EXPORT void commitTransaction(const IDBResourceIdentifier&, uint64_t pendingRequestCount);
     WEBCORE_EXPORT void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier&);
     WEBCORE_EXPORT void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&);
     WEBCORE_EXPORT void renameObjectStore(const IDBRequestData&, uint64_t objectStoreIdentifier, const String& newName);

Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -101,12 +101,30 @@
     return m_transactionInfo.mode() == IDBTransactionMode::Readonly;
 }   
 
-void UniqueIDBDatabaseTransaction::commit()
+void UniqueIDBDatabaseTransaction::commit(uint64_t pendingRequestCount)
 {
     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::commit");
 
     auto database = databaseConnection().database();
 
+    std::optional<IDBError> errorInPendingRequests;
+    while (pendingRequestCount--) {
+        auto error = m_requestResults.takeLast();
+        if (!error.isNull()) {
+            errorInPendingRequests = error;
+            break;
+        }
+    }
+
+    if (errorInPendingRequests) {
+        database->abortTransaction(*this, [this, &errorInPendingRequests](auto&) {
+            LOG(IndexedDB, "UniqueIDBDatabaseTransaction::commit with error (callback)");
+
+            m_databaseConnection->didCommitTransaction(*this, *errorInPendingRequests);
+        });
+        return;
+    }
+
     database->commitTransaction(*this, [this](auto& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::commit (callback)");
 
@@ -127,6 +145,8 @@
     database->createObjectStore(*this, info, [this, requestData](auto& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createObjectStore (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().didCreateObjectStore(IDBResultData::createObjectStoreSuccess(requestData.requestIdentifier()));
         else
@@ -147,6 +167,8 @@
     database->deleteObjectStore(*this, objectStoreName, [this, requestData](const IDBError& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteObjectStore (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().didDeleteObjectStore(IDBResultData::deleteObjectStoreSuccess(requestData.requestIdentifier()));
         else
@@ -167,6 +189,8 @@
     database->renameObjectStore(*this, objectStoreIdentifier, newName, [this, requestData](auto& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::renameObjectStore (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().didRenameObjectStore(IDBResultData::renameObjectStoreSuccess(requestData.requestIdentifier()));
         else
@@ -186,6 +210,8 @@
     database->clearObjectStore(*this, objectStoreIdentifier, [this, requestData](auto& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::clearObjectStore (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().didClearObjectStore(IDBResultData::clearObjectStoreSuccess(requestData.requestIdentifier()));
         else
@@ -206,6 +232,8 @@
     database->createIndex(*this, info, [this, requestData](auto& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createIndex (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().didCreateIndex(IDBResultData::createIndexSuccess(requestData.requestIdentifier()));
         else
@@ -226,6 +254,8 @@
     database->deleteIndex(*this, objectStoreIdentifier, indexName, [this, requestData](auto& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createIndex (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().didDeleteIndex(IDBResultData::deleteIndexSuccess(requestData.requestIdentifier()));
         else
@@ -246,6 +276,8 @@
     database->renameIndex(*this, objectStoreIdentifier, indexIdentifier, newName, [this, requestData](auto& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::renameIndex (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().didRenameIndex(IDBResultData::renameIndexSuccess(requestData.requestIdentifier()));
         else
@@ -267,6 +299,8 @@
     database->putOrAdd(requestData, keyData, value, overwriteMode, [this, requestData](auto& error, const IDBKeyData& key) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::putOrAdd (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().connectionToClient().didPutOrAdd(IDBResultData::putOrAddSuccess(requestData.requestIdentifier(), key));
         else
@@ -286,6 +320,8 @@
     database->getRecord(requestData, getRecordData, [this, requestData](auto& error, const IDBGetResult& result) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getRecord (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().connectionToClient().didGetRecord(IDBResultData::getRecordSuccess(requestData.requestIdentifier(), result));
         else
@@ -305,6 +341,8 @@
     database->getAllRecords(requestData, getAllRecordsData, [this, requestData](auto& error, const IDBGetAllResult& result) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getAllRecords (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().connectionToClient().didGetAllRecords(IDBResultData::getAllRecordsSuccess(requestData.requestIdentifier(), result));
         else
@@ -324,6 +362,8 @@
     database->getCount(requestData, keyRangeData, [this, requestData](auto& error, uint64_t count) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getCount (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().connectionToClient().didGetCount(IDBResultData::getCountSuccess(requestData.requestIdentifier(), count));
         else
@@ -343,6 +383,8 @@
     database->deleteRecord(requestData, keyRangeData, [this, requestData](auto& error) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteRecord (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().connectionToClient().didDeleteRecord(IDBResultData::deleteRecordSuccess(requestData.requestIdentifier()));
         else
@@ -362,6 +404,8 @@
     database->openCursor(requestData, info, [this, requestData](auto& error, const IDBGetResult& result) {
         LOG(IndexedDB, "UniqueIDBDatabaseTransaction::openCursor (callback)");
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().connectionToClient().didOpenCursor(IDBResultData::openCursorSuccess(requestData.requestIdentifier(), result));
         else
@@ -384,6 +428,8 @@
         if (option == IndexedDB::CursorIterateOption::DoNotReply)
             return;
 
+        m_requestResults.append(error);
+
         if (error.isNull())
             databaseConnection().connectionToClient().didIterateCursor(IDBResultData::iterateCursorSuccess(requestData.requestIdentifier(), result));
         else

Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h (280052 => 280053)


--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h	2021-07-19 23:09:48 UTC (rev 280053)
@@ -27,6 +27,7 @@
 
 #include "IDBError.h"
 #include "IDBTransactionInfo.h"
+#include <wtf/Deque.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
 
@@ -65,7 +66,7 @@
 
     void abort();
     void abortWithoutCallback();
-    void commit();
+    void commit(uint64_t pendingRequestCount);
 
     void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&);
     void deleteObjectStore(const IDBRequestData&, const String& objectStoreName);
@@ -100,6 +101,7 @@
     Vector<uint64_t> m_objectStoreIdentifiers;
 
     std::optional<IDBError> m_mainThreadAbortResult;
+    Deque<IDBError> m_requestResults;
 };
 
 } // namespace IDBServer

Modified: trunk/Source/WebCore/loader/EmptyClients.cpp (280052 => 280053)


--- trunk/Source/WebCore/loader/EmptyClients.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebCore/loader/EmptyClients.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -181,7 +181,7 @@
         void deleteDatabase(const IDBRequestData&) final { }
         void openDatabase(const IDBRequestData&) final { }
         void abortTransaction(const IDBResourceIdentifier&) final { }
-        void commitTransaction(const IDBResourceIdentifier&) final { }
+        void commitTransaction(const IDBResourceIdentifier&, uint64_t) final { }
         void didFinishHandlingVersionChangeTransaction(uint64_t, const IDBResourceIdentifier&) final { }
         void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&) final { }
         void deleteObjectStore(const IDBRequestData&, const String&) final { }

Modified: trunk/Source/WebKit/ChangeLog (280052 => 280053)


--- trunk/Source/WebKit/ChangeLog	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebKit/ChangeLog	2021-07-19 23:09:48 UTC (rev 280053)
@@ -1,3 +1,19 @@
+2021-07-19  Sihui Liu  <[email protected]>
+
+        Implement IDBTransaction.commit()
+        https://bugs.webkit.org/show_bug.cgi?id=227815
+        <rdar://problem/80651270>
+
+        Reviewed by Brady Eidson.
+
+        * NetworkProcess/IndexedDB/WebIDBServer.cpp:
+        (WebKit::WebIDBServer::commitTransaction):
+        * NetworkProcess/IndexedDB/WebIDBServer.h:
+        * NetworkProcess/IndexedDB/WebIDBServer.messages.in:
+        * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
+        (WebKit::WebIDBConnectionToServer::commitTransaction):
+        * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h:
+
 2021-07-19  Wenson Hsieh  <[email protected]>
 
         Revert a debug assertion that was added in r280019

Modified: trunk/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.cpp (280052 => 280053)


--- trunk/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -182,12 +182,12 @@
     m_server->abortTransaction(transactionIdentifier);
 }
 
-void WebIDBServer::commitTransaction(const WebCore::IDBResourceIdentifier& transactionIdentifier)
+void WebIDBServer::commitTransaction(const WebCore::IDBResourceIdentifier& transactionIdentifier, uint64_t pendingRequestCount)
 {
     ASSERT(!RunLoop::isMain());
 
     Locker locker { m_serverLock };
-    m_server->commitTransaction(transactionIdentifier);
+    m_server->commitTransaction(transactionIdentifier, pendingRequestCount);
 }
 
 void WebIDBServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier)

Modified: trunk/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.h (280052 => 280053)


--- trunk/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.h	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.h	2021-07-19 23:09:48 UTC (rev 280053)
@@ -60,7 +60,7 @@
     void openDatabase(const WebCore::IDBRequestData&);
     void deleteDatabase(const WebCore::IDBRequestData&);
     void abortTransaction(const WebCore::IDBResourceIdentifier&);
-    void commitTransaction(const WebCore::IDBResourceIdentifier&);
+    void commitTransaction(const WebCore::IDBResourceIdentifier&, uint64_t pendingRequestCount);
     void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier&);
     void createObjectStore(const WebCore::IDBRequestData&, const WebCore::IDBObjectStoreInfo&);
     void deleteObjectStore(const WebCore::IDBRequestData&, const String& objectStoreName);

Modified: trunk/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.messages.in (280052 => 280053)


--- trunk/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.messages.in	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.messages.in	2021-07-19 23:09:48 UTC (rev 280053)
@@ -24,7 +24,7 @@
     DeleteDatabase(WebCore::IDBRequestData requestData)
     OpenDatabase(WebCore::IDBRequestData requestData)
     AbortTransaction(WebCore::IDBResourceIdentifier transactionIdentifier)
-    CommitTransaction(WebCore::IDBResourceIdentifier transactionIdentifier)
+    CommitTransaction(WebCore::IDBResourceIdentifier transactionIdentifier, uint64_t pendingRequestCount)
     DidFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, WebCore::IDBResourceIdentifier transactionIdentifier)
     CreateObjectStore(WebCore::IDBRequestData requestData, WebCore::IDBObjectStoreInfo info)
     DeleteObjectStore(WebCore::IDBRequestData requestData, String objectStoreName)

Modified: trunk/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp (280052 => 280053)


--- trunk/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -95,9 +95,9 @@
     send(Messages::WebIDBServer::AbortTransaction(transactionIdentifier));
 }
 
-void WebIDBConnectionToServer::commitTransaction(const IDBResourceIdentifier& transactionIdentifier)
+void WebIDBConnectionToServer::commitTransaction(const IDBResourceIdentifier& transactionIdentifier, uint64_t pendingRequestCount)
 {
-    send(Messages::WebIDBServer::CommitTransaction(transactionIdentifier));
+    send(Messages::WebIDBServer::CommitTransaction(transactionIdentifier, pendingRequestCount));
 }
 
 void WebIDBConnectionToServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)

Modified: trunk/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h (280052 => 280053)


--- trunk/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h	2021-07-19 23:09:48 UTC (rev 280053)
@@ -55,7 +55,7 @@
     void deleteDatabase(const WebCore::IDBRequestData&) final;
     void openDatabase(const WebCore::IDBRequestData&) final;
     void abortTransaction(const WebCore::IDBResourceIdentifier&) final;
-    void commitTransaction(const WebCore::IDBResourceIdentifier&) final;
+    void commitTransaction(const WebCore::IDBResourceIdentifier&, uint64_t pendingRequestCount) final;
     void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier&) final;
     void createObjectStore(const WebCore::IDBRequestData&, const WebCore::IDBObjectStoreInfo&) final;
     void deleteObjectStore(const WebCore::IDBRequestData&, const String& objectStoreName) final;

Modified: trunk/Source/WebKitLegacy/ChangeLog (280052 => 280053)


--- trunk/Source/WebKitLegacy/ChangeLog	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebKitLegacy/ChangeLog	2021-07-19 23:09:48 UTC (rev 280053)
@@ -1,3 +1,15 @@
+2021-07-19  Sihui Liu  <[email protected]>
+
+        Implement IDBTransaction.commit()
+        https://bugs.webkit.org/show_bug.cgi?id=227815
+        <rdar://problem/80651270>
+
+        Reviewed by Brady Eidson.
+
+        * Storage/InProcessIDBServer.cpp:
+        (InProcessIDBServer::commitTransaction):
+        * Storage/InProcessIDBServer.h:
+
 2021-07-15  Chris Dumez  <[email protected]>
 
         Add initial support for BroadcastChannel behind a runtime flag

Modified: trunk/Source/WebKitLegacy/Storage/InProcessIDBServer.cpp (280052 => 280053)


--- trunk/Source/WebKitLegacy/Storage/InProcessIDBServer.cpp	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebKitLegacy/Storage/InProcessIDBServer.cpp	2021-07-19 23:09:48 UTC (rev 280053)
@@ -270,11 +270,11 @@
     });
 }
 
-void InProcessIDBServer::commitTransaction(const WebCore::IDBResourceIdentifier& resourceIdentifier)
+void InProcessIDBServer::commitTransaction(const WebCore::IDBResourceIdentifier& resourceIdentifier, uint64_t pendingCountRequest)
 {
-    dispatchTask([this, protectedThis = makeRef(*this), resourceIdentifier = resourceIdentifier.isolatedCopy()] {
+    dispatchTask([this, protectedThis = makeRef(*this), resourceIdentifier = resourceIdentifier.isolatedCopy(), pendingCountRequest] {
         Locker locker { m_serverLock };
-        m_server->commitTransaction(resourceIdentifier);
+        m_server->commitTransaction(resourceIdentifier, pendingCountRequest);
     });
 }
 

Modified: trunk/Source/WebKitLegacy/Storage/InProcessIDBServer.h (280052 => 280053)


--- trunk/Source/WebKitLegacy/Storage/InProcessIDBServer.h	2021-07-19 22:59:14 UTC (rev 280052)
+++ trunk/Source/WebKitLegacy/Storage/InProcessIDBServer.h	2021-07-19 23:09:48 UTC (rev 280053)
@@ -65,7 +65,7 @@
     void deleteDatabase(const WebCore::IDBRequestData&) final;
     void openDatabase(const WebCore::IDBRequestData&) final;
     void abortTransaction(const WebCore::IDBResourceIdentifier&) final;
-    void commitTransaction(const WebCore::IDBResourceIdentifier&) final;
+    void commitTransaction(const WebCore::IDBResourceIdentifier&, uint64_t pendingCountRequest) final;
     void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier&) final;
     void createObjectStore(const WebCore::IDBRequestData&, const WebCore::IDBObjectStoreInfo&) final;
     void deleteObjectStore(const WebCore::IDBRequestData&, const String& objectStoreName) final;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to