Bug 1149815 - Properly handle IDBDatabase.close() called during a versionchange transaction, r=janv.

This commit is contained in:
Ben Turner 2015-06-20 09:08:30 -07:00
parent 778f5ee935
commit af54c09757
22 changed files with 131 additions and 35 deletions

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<!--
Bug 970517 - Storage inspector front end - tests
@ -41,6 +41,7 @@ function success(event) {
window.idbGenerator = function*(callback) {
let request = indexedDB.open("idb1", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
request.onerror = function(e) {
throw new Error("error opening db connection");
};
@ -60,18 +61,18 @@ window.idbGenerator = function*(callback) {
store2.add({id2: 1, name: "foo", email: "foo@bar.com", extra: "baz"}).onsuccess = success;
yield undefined;
store1.transaction.oncomplete = success;
yield undefined;
db.close();
request = indexedDB.open("idb2", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
event = yield undefined;
let db2 = event.target.result;
let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
store3.createIndex("name2", "name2", { unique: true });
store3.transaction.oncomplete = success;
yield undefined;
db2.close();
console.log("added cookies and stuff from main page");

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<!--
Bug 970517 - Storage inspector front end - tests
@ -35,6 +35,7 @@ function success(event) {
window.idbGenerator = function*(callback) {
let request = indexedDB.open("idb1", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
request.onerror = function(e) {
throw new Error("error opening db connection");
};
@ -54,18 +55,18 @@ window.idbGenerator = function*(callback) {
store2.add({id2: 1, name: "foo", email: "foo@bar.com", extra: "baz"}).onsuccess = success;
yield undefined;
store1.transaction.oncomplete = success;
yield undefined;
db.close();
request = indexedDB.open("idb2", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
event = yield undefined;
let db2 = event.target.result;
let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
store3.createIndex("name2", "name2", { unique: true });
store3.transaction.oncomplete = success;
yield undefined;
db2.close();
console.log("added cookies and stuff from main page");

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<!--
Iframe for testing multiple host detetion in storage actor
@ -20,6 +20,7 @@ function success(event) {
window.idbGenerator = function*(callback) {
let request = indexedDB.open("idb-s1", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
request.onerror = function(e) {
throw new Error("error opening db connection");
};
@ -31,12 +32,13 @@ window.idbGenerator = function*(callback) {
yield undefined;
store1.add({id: 7, name: "foo2", email: "foo2@bar.com"}).onsuccess = success;
yield undefined;
store1.transaction.oncomplete = success;
yield undefined;
db.close();
request = indexedDB.open("idb-s2", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
event = yield undefined;
let db2 = event.target.result;
@ -44,7 +46,7 @@ window.idbGenerator = function*(callback) {
store3.createIndex("name2", "name2", { unique: true });
store3.add({id3: 16, name2: "foo", email: "foo@bar.com"}).onsuccess = success;
yield undefined;
store3.transaction.oncomplete = success;
yield undefined;
db2.close();
console.log("added cookies and stuff from secured iframe");

View File

@ -1262,14 +1262,26 @@ BackgroundFactoryRequestChild::HandleResponse(
static_cast<BackgroundDatabaseChild*>(aResponse.databaseChild());
MOZ_ASSERT(databaseActor);
databaseActor->EnsureDOMObject();
IDBDatabase* database = databaseActor->GetDOMObject();
MOZ_ASSERT(database);
if (!database) {
databaseActor->EnsureDOMObject();
ResultHelper helper(mRequest, nullptr, database);
database = databaseActor->GetDOMObject();
MOZ_ASSERT(database);
DispatchSuccessEvent(&helper);
MOZ_ASSERT(!database->IsClosed());
}
if (database->IsClosed()) {
// If the database was closed already, which is only possible if we fired an
// "upgradeneeded" event, then we shouldn't fire a "success" event here.
// Instead we fire an error event with AbortErr.
DispatchErrorEvent(mRequest, NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
} else {
ResultHelper helper(mRequest, nullptr, database);
DispatchSuccessEvent(&helper);
}
databaseActor->ReleaseDOMObject();

View File

@ -19690,7 +19690,18 @@ void
OpenDatabaseOp::NoteDatabaseClosed(Database* aDatabase)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State_WaitingForOtherDatabasesToClose);
MOZ_ASSERT(aDatabase);
MOZ_ASSERT(mState == State_WaitingForOtherDatabasesToClose ||
mState == State_DatabaseWorkVersionChange);
if (mState == State_DatabaseWorkVersionChange) {
MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty());
MOZ_ASSERT(mRequestedVersion >
aDatabase->Metadata()->mCommonMetadata.version(),
"Must only be closing databases for a previous version!");
return;
}
MOZ_ASSERT(!mMaybeBlockedDatabases.IsEmpty());
bool actorDestroyed = IsActorDestroyed() || mDatabase->IsActorDestroyed();

View File

@ -58,6 +58,9 @@
let event = yield undefined;
let db = event.target.result;
db.onversionchange = function(event) {
event.target.close();
};
is(db.version, 1, "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
@ -104,6 +107,9 @@
event = yield undefined;
db = event.target.result;
db.onversionchange = function(event) {
event.target.close();
};
event.target.transaction.oncomplete = grabEventAndContinueHandler;
event.target.transaction.onabort = unexpectedSuccessHandler;
@ -153,14 +159,15 @@
ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
ok(db.objectStoreNames.contains("bar"), "Has correct objectStore");
db.close();
request = indexedDB.open(window.location.pathname, 2);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
event = yield undefined;
db = event.target.result;
db.onversionchange = function(event) {
event.target.close();
};
trans = event.target.transaction;
trans.oncomplete = unexpectedSuccessHandler;

View File

@ -12,6 +12,7 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = request.result;
@ -33,6 +34,9 @@ function testSteps()
request.onsuccess = unexpectedSuccessHandler;
yield undefined;
// Wait for success.
yield undefined;
finishTest();
yield undefined;
}

View File

@ -29,6 +29,7 @@ function testSteps()
request = indexedDB.open(name, i + 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let db = event.target.result;
@ -85,6 +86,10 @@ function testSteps()
ok(true, "7");
ok(obj.data, event.target.result.data,
"Unique index was properly updated.");
// Wait for success
yield undefined;
db.close();
}

View File

@ -16,6 +16,7 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
@ -372,6 +373,11 @@ function testSteps()
is(keyIndex, -1, "Saw all added items");
// Wait for success
yield undefined;
db.close();
finishTest();
yield undefined;
}

View File

@ -13,6 +13,7 @@ function testSteps()
var request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
var event = yield undefined;
is(event.target.source, null, "correct event.target.source");
@ -27,6 +28,9 @@ function testSteps()
ok(event.target.source === objectStore, "correct event.source");
// Wait for success
yield undefined;
finishTest();
yield undefined;
}

View File

@ -12,6 +12,7 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
@ -276,6 +277,9 @@ function testSteps()
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
// Wait for success
yield undefined;
finishTest();
yield undefined;
}
}

View File

@ -27,6 +27,9 @@ function testSteps()
let event = yield undefined;
let db = event.target.result;
db.onversionchange = function(event) {
event.target.close();
};
let objectStore =
db.createObjectStore(objectStores[i].name,
@ -48,7 +51,6 @@ function testSteps()
event = yield undefined;
ok(event.target.result == 1 || event.target.result == 2, "Good id");
db.close();
}
executeSoon(function() { testGenerator.next(); });

View File

@ -12,6 +12,7 @@ function testSteps()
var request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
var event = yield undefined;
var db = event.target.result;
@ -45,6 +46,9 @@ function testSteps()
// Ensure that the id was also stored on the object.
is(event.target.result.id, id, "The object had the id stored on it.");
// Wait for success
yield undefined;
finishTest();
yield undefined;
}

View File

@ -42,9 +42,13 @@ function testSteps()
let request = indexedDB.open(name, i+1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onversionchange = function(event) {
event.target.close();
};
let objectStore = db.createObjectStore(test.name,
{ keyPath: test.keyName,
@ -77,7 +81,9 @@ function testSteps()
event = yield undefined;
ok(event.target.result === undefined, "Object was deleted");
db.close();
// Wait for success
yield undefined;
}
finishTest();

View File

@ -16,6 +16,7 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
@ -42,10 +43,13 @@ function testSteps()
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.target.result, testInt.value, "Got the right value");
finishTest();
};
}
// Wait for success
yield undefined;
finishTest();
yield undefined;
}

View File

@ -16,6 +16,7 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
@ -42,9 +43,12 @@ function testSteps()
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.target.result, testInt.value, "Got the right value");
finishTest();
};
}
// Wait for success
yield undefined;
}
finishTest();
yield undefined;
}

View File

@ -13,8 +13,12 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
let db = event.target.result;
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
@ -40,13 +44,20 @@ function testSteps()
event.target.transaction.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
// Wait for success.
event = yield undefined;
db.close();
request = indexedDB.open(name, 2);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
event = yield undefined;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
db = event.target.result;
let trans = event.target.transaction;
@ -87,6 +98,9 @@ function testSteps()
trans.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
// Wait for success.
event = yield undefined;
db.close();
request = indexedDB.open(name, 3);

View File

@ -14,6 +14,7 @@ function testSteps()
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
is(request.readyState, "done", "Correct readyState");
@ -42,6 +43,9 @@ function testSteps()
ok(event.target.result, "Got something");
is(request.readyState, "done", "Correct readyState");
// Wait for success
yield undefined;
finishTest();
yield undefined;
}

View File

@ -15,6 +15,7 @@ function testSteps()
let event = yield undefined;
let db = event.target.result;
db.close();
// Check default state.
is(db.version, 1, "Correct default version for a new database.");
@ -24,14 +25,13 @@ function testSteps()
42,
];
db.close();
for (let i = 0; i < versions.length; i++) {
let version = versions[i];
let request = indexedDB.open(name, version);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
@ -39,8 +39,9 @@ function testSteps()
is(db.version, version, "Database version number updated correctly");
is(event.target.transaction.mode, "versionchange", "Correct mode");
executeSoon(function() { testGenerator.next(); });
// Wait for success
yield undefined;
db.close();
}

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<!--
Bug 965872 - Storage inspector actor with cookies, local storage and session storage.
@ -33,6 +33,7 @@ function success(event) {
window.idbGenerator = function*(callback) {
let request = indexedDB.open("idb1", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
request.onerror = function(e) {
throw new Error("error opening db connection");
};
@ -52,18 +53,17 @@ window.idbGenerator = function*(callback) {
store2.add({id2: 1, name: "foo", email: "foo@bar.com", extra: "baz"}).onsuccess = success;
yield undefined;
store1.transaction.oncomplete = success;
yield undefined;
db.close();
request = indexedDB.open("idb2", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
event = yield undefined;
let db2 = event.target.result;
let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
store3.createIndex("name2", "name2", { unique: true });
store3.transaction.oncomplete = success;
yield undefined;
db2.close();
console.log("added cookies and stuff from main page");

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<!--
Bug 965872 - Storage inspector actor with cookies, local storage and session storage.
@ -35,6 +35,7 @@ function success(event) {
window.idbGenerator = function*(callback) {
let request = indexedDB.open("idb1", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
request.onerror = function(e) {
throw new Error("error opening db connection");
};
@ -54,18 +55,17 @@ window.idbGenerator = function*(callback) {
store2.add({id2: 1, name: "foo", email: "foo@bar.com", extra: "baz"}).onsuccess = success;
yield undefined;
store1.transaction.oncomplete = success;
yield undefined;
db.close();
request = indexedDB.open("idb2", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
event = yield undefined;
let db2 = event.target.result;
let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
store3.createIndex("name2", "name2", { unique: true });
store3.transaction.oncomplete = success;
yield undefined;
db2.close();
console.log("added cookies and stuff from main page");

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<!--
Iframe for testing multiple host detetion in storage actor
@ -20,6 +20,7 @@ function success(event) {
window.idbGenerator = function*(callback) {
let request = indexedDB.open("idb-s1", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
request.onerror = function(e) {
throw new Error("error opening db connection");
};
@ -31,12 +32,12 @@ window.idbGenerator = function*(callback) {
yield undefined;
store1.add({id: 7, name: "foo2", email: "foo2@bar.com"}).onsuccess = success;
yield undefined;
store1.transaction.oncomplete = success;
yield undefined;
db.close();
request = indexedDB.open("idb-s2", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
event = yield undefined;
let db2 = event.target.result;
@ -44,7 +45,6 @@ window.idbGenerator = function*(callback) {
store3.createIndex("name2", "name2", { unique: true });
store3.add({id3: 16, name2: "foo", email: "foo@bar.com"}).onsuccess = success;
yield undefined;
store3.transaction.oncomplete = success;
yield undefined;
db2.close();
console.log("added cookies and stuff from secured iframe");