Title: [113502] branches/chromium/1084
- Revision
- 113502
- Author
- jsb...@chromium.org
- Date
- 2012-04-06 14:49:13 -0700 (Fri, 06 Apr 2012)
Log Message
Merge 112740 - 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):
TBR=jsb...@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10007047
Modified Paths
Added Paths
Diff
Modified: branches/chromium/1084/LayoutTests/platform/chromium/test_expectations.txt (113501 => 113502)
--- branches/chromium/1084/LayoutTests/platform/chromium/test_expectations.txt 2012-04-06 21:49:11 UTC (rev 113501)
+++ branches/chromium/1084/LayoutTests/platform/chromium/test_expectations.txt 2012-04-06 21:49:13 UTC (rev 113502)
@@ -4327,3 +4327,6 @@
BUGWK82372 LINUX X86 RELEASE : css3/filters/custom/effect-custom-parameters.html = IMAGE
BUGWK82269 DEBUG: media/track/track-delete-during-setup.html = CRASH
+
+// This test depends on Worker behavior that is broken in DRT
+BUGWK82776 : storage/indexeddb/dont-commit-on-blocked.html = PASS FAIL
Copied: branches/chromium/1084/LayoutTests/storage/indexeddb/dont-commit-on-blocked-expected.txt (from rev 112740, trunk/LayoutTests/storage/indexeddb/dont-commit-on-blocked-expected.txt) (0 => 113502)
--- branches/chromium/1084/LayoutTests/storage/indexeddb/dont-commit-on-blocked-expected.txt (rev 0)
+++ branches/chromium/1084/LayoutTests/storage/indexeddb/dont-commit-on-blocked-expected.txt 2012-04-06 21:49:13 UTC (rev 113502)
@@ -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
+
Copied: branches/chromium/1084/LayoutTests/storage/indexeddb/dont-commit-on-blocked.html (from rev 112740, trunk/LayoutTests/storage/indexeddb/dont-commit-on-blocked.html) (0 => 113502)
--- branches/chromium/1084/LayoutTests/storage/indexeddb/dont-commit-on-blocked.html (rev 0)
+++ branches/chromium/1084/LayoutTests/storage/indexeddb/dont-commit-on-blocked.html 2012-04-06 21:49:13 UTC (rev 113502)
@@ -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>
Copied: branches/chromium/1084/LayoutTests/storage/indexeddb/resources/dont-commit-on-blocked-worker.js (from rev 112740, trunk/LayoutTests/storage/indexeddb/resources/dont-commit-on-blocked-worker.js) (0 => 113502)
--- branches/chromium/1084/LayoutTests/storage/indexeddb/resources/dont-commit-on-blocked-worker.js (rev 0)
+++ branches/chromium/1084/LayoutTests/storage/indexeddb/resources/dont-commit-on-blocked-worker.js 2012-04-06 21:49:13 UTC (rev 113502)
@@ -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: branches/chromium/1084/Source/WebCore/Modules/indexeddb/IDBRequest.cpp (113501 => 113502)
--- branches/chromium/1084/Source/WebCore/Modules/indexeddb/IDBRequest.cpp 2012-04-06 21:49:11 UTC (rev 113501)
+++ branches/chromium/1084/Source/WebCore/Modules/indexeddb/IDBRequest.cpp 2012-04-06 21:49:13 UTC (rev 113502)
@@ -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
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes