Title: [112740] trunk
Revision
112740
Author
[email protected]
Date
2012-03-30 16:04:47 -0700 (Fri, 30 Mar 2012)

Log Message

IndexedDB: Race condition causes version change transaction to commit after onblocked
https://bugs.webkit.org/show_bug.cgi?id=82678

Source/WebCore:

For a version change event, the blocked and success events could both be queued
before either is dispatched. The transaction would erroneously be allowed to commit
after the blocked event was dispatched; it should not be, as the request was not
finished.

Reviewed by Tony Chang.

Test: storage/indexeddb/dont-commit-on-blocked.html

* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::dispatchEvent):

LayoutTests:

Landing test marked PASS FAIL as WK82776 prevents it from running in DRT; will
run it as a Chromium browser test for now.

Reviewed by Tony Chang.

* platform/chromium/test_expectations.txt:
* storage/indexeddb/dont-commit-on-blocked.html: Added.
* storage/indexeddb/resources/dont-commit-on-blocked-worker.js: Added.
(request.onsuccess):
(onSetVersionBlocked):
(onSetVersionSuccess):
(onTransactionComplete):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (112739 => 112740)


--- trunk/LayoutTests/ChangeLog	2012-03-30 23:00:46 UTC (rev 112739)
+++ trunk/LayoutTests/ChangeLog	2012-03-30 23:04:47 UTC (rev 112740)
@@ -1,3 +1,21 @@
+2012-03-30  Joshua Bell  <[email protected]>
+
+        IndexedDB: Race condition causes version change transaction to commit after onblocked
+        https://bugs.webkit.org/show_bug.cgi?id=82678
+
+        Landing test marked PASS FAIL as WK82776 prevents it from running in DRT; will
+        run it as a Chromium browser test for now.
+
+        Reviewed by Tony Chang.
+
+        * platform/chromium/test_expectations.txt:
+        * storage/indexeddb/dont-commit-on-blocked.html: Added.
+        * storage/indexeddb/resources/dont-commit-on-blocked-worker.js: Added.
+        (request.onsuccess):
+        (onSetVersionBlocked):
+        (onSetVersionSuccess):
+        (onTransactionComplete):
+
 2012-03-30  Simon Fraser  <[email protected]>
 
         Skip another cookie test. Tracked by

Modified: trunk/LayoutTests/platform/chromium/test_expectations.txt (112739 => 112740)


--- trunk/LayoutTests/platform/chromium/test_expectations.txt	2012-03-30 23:00:46 UTC (rev 112739)
+++ trunk/LayoutTests/platform/chromium/test_expectations.txt	2012-03-30 23:04:47 UTC (rev 112740)
@@ -4093,3 +4093,6 @@
 BUGWK82717 SNOWLEOPARD : storage/quota-tracking.html = PASS TIMEOUT
 BUGWK82717 SNOWLEOPARD : storage/executesql-accepts-only-one-statement.html = PASS TIMEOUT
 BUGWK82717 SNOWLEOPARD : storage/database-lock-after-reload.html = PASS TIMEOUT
+
+// This test depends on Worker behavior that is broken in DRT
+BUGWK82776 : storage/indexeddb/dont-commit-on-blocked.html = PASS FAIL

Added: trunk/LayoutTests/storage/indexeddb/dont-commit-on-blocked-expected.txt (0 => 112740)


--- trunk/LayoutTests/storage/indexeddb/dont-commit-on-blocked-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/dont-commit-on-blocked-expected.txt	2012-03-30 23:04:47 UTC (rev 112740)
@@ -0,0 +1,51 @@
+Regression test for WK82678 - don't commit after a blocked event
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+PASS Boolean(indexedDB && IDBCursor && IDBDatabase && IDBDatabaseError && IDBDatabaseException && IDBFactory && IDBIndex && IDBKeyRange && IDBObjectStore && IDBRequest && IDBTransaction) is true
+
+Prepare Database
+request = indexedDB.deleteDatabase('dont-commit-on-blocked')
+request = indexedDB.open('dont-commit-on-blocked')
+db = request.result
+db._onversionchange_ = onVersionChange
+PASS db.version is ""
+db.setVersion('1')
+store = db.createObjectStore('store1')
+
+holdConnection():
+holding connection until versionchange event
+
+Starting worker: resources/dont-commit-on-blocked-worker.js
+[Worker] indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+PASS [Worker] Boolean(indexedDB && IDBCursor && IDBDatabase && IDBDatabaseError && IDBDatabaseException && IDBFactory && IDBIndex && IDBKeyRange && IDBObjectStore && IDBRequest && IDBTransaction) is true
+[Worker] 
+[Worker] opening database connection
+[Worker] request = indexedDB.open('dont-commit-on-blocked')
+[Worker] db = request.result
+[Worker] state = 'setversion'
+[Worker] request = db.setVersion(2)
+[Worker] request._onblocked_ = onSetVersionBlocked
+[Worker] request._onsuccess_ = onSetVersionSuccess
+[Worker] spinning for 100ms to let events be queued but prevent dispatch
+[Worker] done spinning
+[Worker] 
+[Worker] onSetVersionSuccess():
+FAIL [Worker] state should be blocked. Was setversion.
+[Worker] state = 'success'
+[Worker] creating object store - will fail if transaction commited after blocked event
+[Worker] db.createObjectStore('store2')
+[Worker] transaction = request.result
+[Worker] transaction._oncomplete_ = onTransactionComplete
+[Worker] 
+[Worker] onTransactionComplete
+PASS [Worker] state is "success"
+PASS [Worker] Number(db.version) is 2
+FAIL [Worker] db.objectStoreNames.contains('store1') should be true. Was false.
+PASS [Worker] db.objectStoreNames.contains('store2') is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/storage/indexeddb/dont-commit-on-blocked.html (0 => 112740)


--- trunk/LayoutTests/storage/indexeddb/dont-commit-on-blocked.html	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/dont-commit-on-blocked.html	2012-03-30 23:04:47 UTC (rev 112740)
@@ -0,0 +1,65 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+
+description("Regression test for WK82678 - don't commit after a blocked event");
+
+function test()
+{
+    removeVendorPrefixes();
+    prepareDatabase();
+}
+
+function prepareDatabase()
+{
+    debug("Prepare Database");
+    evalAndLog("request = indexedDB.deleteDatabase('dont-commit-on-blocked')");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = function(e) {
+        evalAndLog("request = indexedDB.open('dont-commit-on-blocked')");
+        request._onerror_ = unexpectedErrorCallback;
+        request._onsuccess_ = function(e) {
+            evalAndLog("db = request.result");
+            db._onerror_ = unexpectedErrorCallback;
+            evalAndLog("db._onversionchange_ = onVersionChange");
+            shouldBeEqualToString("db.version", "");
+            request = evalAndLog("db.setVersion('1')");
+            request._onerror_ = unexpectedErrorCallback;
+            request._onsuccess_ = function(e) {
+                var trans = request.result;
+                evalAndLog("store = db.createObjectStore('store1')");
+                trans._onerror_ = unexpectedErrorCallback;
+                trans._onabort_ = unexpectedAbortCallback;
+                trans._oncomplete_ = holdConnection;
+            };
+        };
+    };
+}
+
+function holdConnection()
+{
+    debug("");
+    debug("holdConnection():");
+    debug("holding connection until versionchange event");
+    debug("");
+    startWorker("resources/dont-commit-on-blocked-worker.js");
+}
+
+function onVersionChange(e)
+{
+    debug("");
+    debug("onVersionChange():");
+    debug("closing connection");
+    evalAndLog("db.close()");
+}
+
+test();
+
+</script>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/storage/indexeddb/resources/dont-commit-on-blocked-worker.js (0 => 112740)


--- trunk/LayoutTests/storage/indexeddb/resources/dont-commit-on-blocked-worker.js	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/resources/dont-commit-on-blocked-worker.js	2012-03-30 23:04:47 UTC (rev 112740)
@@ -0,0 +1,57 @@
+importScripts('../../../fast/js/resources/js-test-pre.js');
+importScripts('shared.js');
+
+removeVendorPrefixes();
+
+debug("opening database connection");
+evalAndLog("request = indexedDB.open('dont-commit-on-blocked')");
+request._onerror_ = unexpectedErrorCallback;
+request._onsuccess_ = function(e) {
+  evalAndLog("db = request.result");
+  db._onerror_ = unexpectedErrorCallback;
+
+  evalAndLog("state = 'setversion'");
+  evalAndLog("request = db.setVersion(2)");
+  evalAndLog("request._onblocked_ = onSetVersionBlocked");
+  evalAndLog("request._onsuccess_ = onSetVersionSuccess");
+  debug("spinning for 100ms to let events be queued but prevent dispatch");
+  var t = Date.now();
+  while ((Date.now() - t) < 100) {
+  }
+  debug("done spinning");
+};
+
+function onSetVersionBlocked(e)
+{
+  debug("");
+  debug("onSetVersionBlocked():");
+  shouldBeEqualToString("state", "setversion");
+  evalAndLog("state = 'blocked'");
+}
+
+function onSetVersionSuccess(e)
+{
+  debug("");
+  debug("onSetVersionSuccess():");
+  shouldBeEqualToString("state", "blocked");
+  evalAndLog("state = 'success'");
+
+  debug("creating object store - will fail if transaction commited after blocked event");
+  evalAndLog("db.createObjectStore('store2')");
+
+  evalAndLog("transaction = request.result");
+  evalAndLog("transaction._oncomplete_ = onTransactionComplete");
+}
+
+function onTransactionComplete(e)
+{
+  debug("");
+  debug("onTransactionComplete");
+
+  shouldBeEqualToString("state", "success");
+
+  shouldBe("Number(db.version)", "2");
+  shouldBeTrue("db.objectStoreNames.contains('store1')");
+  shouldBeTrue("db.objectStoreNames.contains('store2')");
+  finishJSTest();
+}

Modified: trunk/Source/WebCore/ChangeLog (112739 => 112740)


--- trunk/Source/WebCore/ChangeLog	2012-03-30 23:00:46 UTC (rev 112739)
+++ trunk/Source/WebCore/ChangeLog	2012-03-30 23:04:47 UTC (rev 112740)
@@ -1,3 +1,20 @@
+2012-03-30  Joshua Bell  <[email protected]>
+
+        IndexedDB: Race condition causes version change transaction to commit after onblocked
+        https://bugs.webkit.org/show_bug.cgi?id=82678
+
+        For a version change event, the blocked and success events could both be queued
+        before either is dispatched. The transaction would erroneously be allowed to commit
+        after the blocked event was dispatched; it should not be, as the request was not
+        finished.
+
+        Reviewed by Tony Chang.
+
+        Test: storage/indexeddb/dont-commit-on-blocked.html
+
+        * Modules/indexeddb/IDBRequest.cpp:
+        (WebCore::IDBRequest::dispatchEvent):
+
 2012-03-30  Ryosuke Niwa  <[email protected]>
 
         Add a compile assert for the size of FontDescription

Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp (112739 => 112740)


--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp	2012-03-30 23:00:46 UTC (rev 112739)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp	2012-03-30 23:04:47 UTC (rev 112740)
@@ -378,7 +378,7 @@
     if (cursorToNotify)
         cursorToNotify->postSuccessHandlerCallback();
 
-    if (m_transaction) {
+    if (m_transaction && event->type() != eventNames().blockedEvent) {
         // If an error event and the default wasn't prevented...
         if (dontPreventDefault && event->type() == eventNames().errorEvent)
             m_transaction->backend()->abort();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to