Title: [274269] trunk
Revision
274269
Author
sihui_...@apple.com
Date
2021-03-11 00:41:24 -0800 (Thu, 11 Mar 2021)

Log Message

Indexed DB transactions outdated immediately after it just created
https://bugs.webkit.org/show_bug.cgi?id=216769
<rdar://problem/69321075>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Test: storage/indexeddb/transaction-state-active-after-creation.html

Set transaction inactive in microtask checkpoint according to spec:
https://html.spec.whatwg.org/#perform-a-microtask-checkpoint

* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::IDBTransaction):
* dom/EventLoop.cpp:
(WebCore::EventLoopTaskGroup::runAtEndOfMicrotaskCheckpoint):
* dom/EventLoop.h:
* dom/Microtasks.cpp:
(WebCore::MicrotaskQueue::performMicrotaskCheckpoint):
(WebCore::MicrotaskQueue::addCheckpointTask):
* dom/Microtasks.h:
* dom/TaskSource.h:

LayoutTests:

* storage/indexeddb/transaction-state-active-after-creation-expected.txt: Added.
* storage/indexeddb/transaction-state-active-after-creation.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (274268 => 274269)


--- trunk/LayoutTests/ChangeLog	2021-03-11 07:28:47 UTC (rev 274268)
+++ trunk/LayoutTests/ChangeLog	2021-03-11 08:41:24 UTC (rev 274269)
@@ -1,3 +1,14 @@
+2021-03-11  Sihui Liu  <sihui_...@apple.com>
+
+        Indexed DB transactions outdated immediately after it just created
+        https://bugs.webkit.org/show_bug.cgi?id=216769
+        <rdar://problem/69321075>
+
+        Reviewed by Ryosuke Niwa.
+
+        * storage/indexeddb/transaction-state-active-after-creation-expected.txt: Added.
+        * storage/indexeddb/transaction-state-active-after-creation.html: Added.
+
 2021-03-10  Rob Buis  <rb...@igalia.com>
 
         Fix intrinsic-size-005.html

Added: trunk/LayoutTests/storage/indexeddb/transaction-state-active-after-creation-expected.txt (0 => 274269)


--- trunk/LayoutTests/storage/indexeddb/transaction-state-active-after-creation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/transaction-state-active-after-creation-expected.txt	2021-03-11 08:41:24 UTC (rev 274269)
@@ -0,0 +1,13 @@
+dbname = "transaction-state-active-after-creation"
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+transaction = db.transaction("store", "readwrite")
+transaction.objectStore("store").put("value", "key")
+sleep 100ms
+database exists
+transaction = db.transaction("store", "readwrite")
+transaction.objectStore("store").put("value", "key")
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/storage/indexeddb/transaction-state-active-after-creation.html (0 => 274269)


--- trunk/LayoutTests/storage/indexeddb/transaction-state-active-after-creation.html	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/transaction-state-active-after-creation.html	2021-03-11 08:41:24 UTC (rev 274269)
@@ -0,0 +1,80 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script>
+var db = null;
+
+const deleteDatabase = () => {
+    return new Promise((resolve, reject) => {
+        evalAndLog('dbname = "transaction-state-active-after-creation"');
+        let deleteRequest = evalAndLog('indexedDB.deleteDatabase(dbname)');
+        deleteRequest._onsuccess_ = () => resolve();
+        deleteRequest._onerror_ = () => reject();
+    });
+}
+
+const openDatabase = () => {
+    return new Promise((resolve, reject) => {
+        if (db) {
+            debug('database exists');
+            resolve();
+        } else {
+            let openRequest = evalAndLog('indexedDB.open(dbname)');
+            openRequest._onupgradeneeded_ = (event) => {
+                db = event.target.result;
+                db.createObjectStore('store');
+            }
+            openRequest._onsuccess_ =  () => resolve();
+            openRequest._onerror_ = () => reject();
+        }
+    });
+}
+
+const prepareTransaction = async () => {
+    await openDatabase();
+    evalAndLog('transaction = db.transaction("store", "readwrite")');
+}
+
+const putRecord = (key) => {
+    return new Promise((resolve, reject) => {
+        try {
+            putRequest = evalAndLog('transaction.objectStore("store").put("value", "key")');
+            putRequest._onsuccess_ = () => resolve();
+            putRequest._onerror_ = (event) => reject(event);
+        } catch(e) {
+            reject(e);
+        }
+    });
+}
+
+const sleep = (ms) => {
+    return new Promise((resolve) => setTimeout(resolve, ms));
+}
+
+const asyncTest = async() => {
+    await deleteDatabase();
+
+    await prepareTransaction();
+    await putRecord();
+
+    debug('sleep 100ms');
+    await sleep(100);
+
+    await prepareTransaction();
+    putRecord()
+    .then(() => finishJSTest())
+    .catch((error) => {
+        testFailed('Failed to put record');
+        finishJSTest();
+    });
+}
+
+asyncTest();
+</script>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (274268 => 274269)


--- trunk/Source/WebCore/ChangeLog	2021-03-11 07:28:47 UTC (rev 274268)
+++ trunk/Source/WebCore/ChangeLog	2021-03-11 08:41:24 UTC (rev 274269)
@@ -1,3 +1,27 @@
+2021-03-11  Sihui Liu  <sihui_...@apple.com>
+
+        Indexed DB transactions outdated immediately after it just created
+        https://bugs.webkit.org/show_bug.cgi?id=216769
+        <rdar://problem/69321075>
+
+        Reviewed by Ryosuke Niwa.
+
+        Test: storage/indexeddb/transaction-state-active-after-creation.html
+
+        Set transaction inactive in microtask checkpoint according to spec:
+        https://html.spec.whatwg.org/#perform-a-microtask-checkpoint
+
+        * Modules/indexeddb/IDBTransaction.cpp:
+        (WebCore::IDBTransaction::IDBTransaction):
+        * dom/EventLoop.cpp:
+        (WebCore::EventLoopTaskGroup::runAtEndOfMicrotaskCheckpoint):
+        * dom/EventLoop.h:
+        * dom/Microtasks.cpp:
+        (WebCore::MicrotaskQueue::performMicrotaskCheckpoint):
+        (WebCore::MicrotaskQueue::addCheckpointTask):
+        * dom/Microtasks.h:
+        * dom/TaskSource.h:
+
 2021-03-10  Rob Buis  <rb...@igalia.com>
 
         Fix intrinsic-size-005.html

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (274268 => 274269)


--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp	2021-03-11 07:28:47 UTC (rev 274268)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp	2021-03-11 08:41:24 UTC (rev 274269)
@@ -33,6 +33,7 @@
 #include "DOMWindow.h"
 #include "Event.h"
 #include "EventDispatcher.h"
+#include "EventLoop.h"
 #include "EventNames.h"
 #include "EventQueue.h"
 #include "IDBCursorWithValue.h"
@@ -97,8 +98,7 @@
         auto* context = scriptExecutionContext();
         ASSERT(context);
 
-        JSC::VM& vm = context->vm();
-        vm.whenIdle([protectedThis = makeRef(*this)]() {
+        context->eventLoop().runAtEndOfMicrotaskCheckpoint([protectedThis = makeRef(*this)] {
             protectedThis->deactivate();
         });
 

Modified: trunk/Source/WebCore/dom/EventLoop.cpp (274268 => 274269)


--- trunk/Source/WebCore/dom/EventLoop.cpp	2021-03-11 07:28:47 UTC (rev 274268)
+++ trunk/Source/WebCore/dom/EventLoop.cpp	2021-03-11 08:41:24 UTC (rev 274269)
@@ -180,4 +180,12 @@
         m_eventLoop->performMicrotaskCheckpoint();
 }
 
+void EventLoopTaskGroup::runAtEndOfMicrotaskCheckpoint(EventLoop::TaskFunction&& function)
+{
+    if (m_state == State::Stopped || !m_eventLoop)
+        return;
+
+    microtaskQueue().addCheckpointTask(makeUnique<EventLoopFunctionDispatchTask>(TaskSource::IndexedDB, *this, WTFMove(function)));
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/EventLoop.h (274268 => 274269)


--- trunk/Source/WebCore/dom/EventLoop.h	2021-03-11 07:28:47 UTC (rev 274268)
+++ trunk/Source/WebCore/dom/EventLoop.h	2021-03-11 08:41:24 UTC (rev 274269)
@@ -182,6 +182,8 @@
     // https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint
     void performMicrotaskCheckpoint();
 
+    void runAtEndOfMicrotaskCheckpoint(EventLoop::TaskFunction&&);
+
 private:
     enum class State : uint8_t { Running, Suspended, ReadyToStop, Stopped };
 

Modified: trunk/Source/WebCore/dom/Microtasks.cpp (274268 => 274269)


--- trunk/Source/WebCore/dom/Microtasks.cpp	2021-03-11 07:28:47 UTC (rev 274268)
+++ trunk/Source/WebCore/dom/Microtasks.cpp	2021-03-11 08:41:24 UTC (rev 274269)
@@ -67,6 +67,25 @@
 
     vm().finalizeSynchronousJSExecution();
     m_microtaskQueue = WTFMove(toKeep);
+
+    auto checkpointTasks = std::exchange(m_checkpointTasks, { });
+    for (auto& checkpointTask : checkpointTasks) {
+        auto* group = checkpointTask->group();
+        if (!group || group->isStoppedPermanently())
+            continue;
+
+        if (group->isSuspended()) {
+            m_checkpointTasks.append(WTFMove(checkpointTask));
+            continue;
+        }
+
+        checkpointTask->execute();
+    }
 }
 
+void MicrotaskQueue::addCheckpointTask(std::unique_ptr<EventLoopTask>&& task)
+{
+    m_checkpointTasks.append(WTFMove(task));
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/Microtasks.h (274268 => 274269)


--- trunk/Source/WebCore/dom/Microtasks.h	2021-03-11 07:28:47 UTC (rev 274268)
+++ trunk/Source/WebCore/dom/Microtasks.h	2021-03-11 08:41:24 UTC (rev 274269)
@@ -41,6 +41,8 @@
     WEBCORE_EXPORT void append(std::unique_ptr<EventLoopTask>&&);
     WEBCORE_EXPORT void performMicrotaskCheckpoint();
 
+    WEBCORE_EXPORT void addCheckpointTask(std::unique_ptr<EventLoopTask>&&);
+
 private:
     JSC::VM& vm() const { return m_vm.get(); }
 
@@ -48,6 +50,8 @@
     Vector<std::unique_ptr<EventLoopTask>> m_microtaskQueue;
     // For the main thread the VM lives forever. For workers it's lifetime is tied to our owning WorkerGlobalScope. Regardless, we retain the VM here to be safe.
     Ref<JSC::VM> m_vm;
+
+    Vector<std::unique_ptr<EventLoopTask>> m_checkpointTasks;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/TaskSource.h (274268 => 274269)


--- trunk/Source/WebCore/dom/TaskSource.h	2021-03-11 07:28:47 UTC (rev 274268)
+++ trunk/Source/WebCore/dom/TaskSource.h	2021-03-11 08:41:24 UTC (rev 274269)
@@ -33,14 +33,15 @@
     FileReading,
     FontLoading,
     IdleTask,
+    IndexedDB,
     MediaElement,
     Microtask,
     Networking,
     PostedMessageQueue,
+    Speech,
     UserInteraction,
     WebGL,
     WebXR,
-    Speech,
 
     // Internal to WebCore
     InternalAsyncTask, // Safe to re-order or delay.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to