From 5e7a740f3696f260df1b9a3e7b2c0ae4aed7fd14 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Mon, 24 Oct 2011 16:01:11 -0400 Subject: [PATCH] Bug 692911: Refactor some VERSION_CHANGE transaction locking stuff and disallow transaction creation before databases are completely open. r=bent --- dom/indexedDB/AsyncConnectionHelper.cpp | 4 +- dom/indexedDB/AsyncConnectionHelper.h | 5 ++ dom/indexedDB/DatabaseInfo.cpp | 3 +- dom/indexedDB/DatabaseInfo.h | 4 +- dom/indexedDB/IDBDatabase.cpp | 32 +++++++ dom/indexedDB/IDBDatabase.h | 3 + dom/indexedDB/IndexedDatabaseManager.cpp | 79 +++++++++++++--- dom/indexedDB/IndexedDatabaseManager.h | 22 +++++ dom/indexedDB/OpenDatabaseHelper.cpp | 30 ++++++- dom/indexedDB/OpenDatabaseHelper.h | 1 + dom/indexedDB/TransactionThreadPool.cpp | 16 +--- dom/indexedDB/TransactionThreadPool.h | 6 -- dom/indexedDB/test/Makefile.in | 1 + .../test/event_propagation_iframe.html | 2 +- dom/indexedDB/test/leaving_page_iframe.html | 2 +- .../test/test_autoIncrement_indexes.html | 3 + dom/indexedDB/test/test_clear.html | 2 +- .../test_create_index_with_integer_keys.html | 4 +- dom/indexedDB/test/test_cursor_mutation.html | 2 +- dom/indexedDB/test/test_getAll.html | 2 + dom/indexedDB/test/test_index_getAll.html | 4 +- .../test/test_index_getAllObjects.html | 2 +- .../test/test_index_object_cursors.html | 2 +- dom/indexedDB/test/test_indexes.html | 2 +- .../test/test_indexes_bad_values.html | 2 + dom/indexedDB/test/test_object_identity.html | 2 +- dom/indexedDB/test/test_odd_result_order.html | 2 +- dom/indexedDB/test/test_open_objectStore.html | 2 +- .../test/test_overlapping_transactions.html | 2 +- .../test/test_readonly_transactions.html | 3 + .../test/test_setVersion_exclusion.html | 90 +++++++++++++++++++ .../test/test_success_events_after_abort.html | 2 +- .../test/test_transaction_abort.html | 3 + .../test/test_transaction_lifetimes.html | 2 +- .../test_transaction_lifetimes_nested.html | 2 +- .../test/test_writer_starvation.html | 2 +- 36 files changed, 289 insertions(+), 58 deletions(-) create mode 100644 dom/indexedDB/test/test_setVersion_exclusion.html diff --git a/dom/indexedDB/AsyncConnectionHelper.cpp b/dom/indexedDB/AsyncConnectionHelper.cpp index 19e87f8c63b..df2b7b340d4 100644 --- a/dom/indexedDB/AsyncConnectionHelper.cpp +++ b/dom/indexedDB/AsyncConnectionHelper.cpp @@ -560,8 +560,8 @@ TransactionPoolEventTarget::Dispatch(nsIRunnable* aRunnable, NS_ASSERTION(aRunnable, "Null pointer!"); NS_ASSERTION(aFlags == NS_DISPATCH_NORMAL, "Unsupported!"); - TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate(); - NS_ENSURE_TRUE(pool, NS_ERROR_FAILURE); + TransactionThreadPool* pool = TransactionThreadPool::Get(); + NS_ASSERTION(pool, "This should never be null!"); return pool->Dispatch(mTransaction, aRunnable, false, nsnull); } diff --git a/dom/indexedDB/AsyncConnectionHelper.h b/dom/indexedDB/AsyncConnectionHelper.h index b0038d48e3a..6f72a567f4a 100644 --- a/dom/indexedDB/AsyncConnectionHelper.h +++ b/dom/indexedDB/AsyncConnectionHelper.h @@ -125,6 +125,11 @@ public: static IDBTransaction* GetCurrentTransaction(); + bool HasTransaction() + { + return mTransaction; + } + nsISupports* GetSource() { return mRequest ? mRequest->Source() : nsnull; diff --git a/dom/indexedDB/DatabaseInfo.cpp b/dom/indexedDB/DatabaseInfo.cpp index f7ed1136285..0433aa75da8 100644 --- a/dom/indexedDB/DatabaseInfo.cpp +++ b/dom/indexedDB/DatabaseInfo.cpp @@ -85,7 +85,8 @@ EnumerateObjectStoreNames(const nsAString& aKey, DatabaseInfo::DatabaseInfo() : id(0), nextObjectStoreId(1), - nextIndexId(1) + nextIndexId(1), + runningVersionChange(false) { MOZ_COUNT_CTOR(DatabaseInfo); } diff --git a/dom/indexedDB/DatabaseInfo.h b/dom/indexedDB/DatabaseInfo.h index 1fdab7e3285..1f2ff398e0a 100644 --- a/dom/indexedDB/DatabaseInfo.h +++ b/dom/indexedDB/DatabaseInfo.h @@ -54,7 +54,8 @@ struct DatabaseInfo ~DatabaseInfo(); #else DatabaseInfo() - : id(0), nextObjectStoreId(1), nextIndexId(1) { } + : id(0), nextObjectStoreId(1), nextIndexId(1), runningVersionChange(false) + { } #endif static bool Get(PRUint32 aId, @@ -73,6 +74,7 @@ struct DatabaseInfo nsString filePath; PRInt64 nextObjectStoreId; PRInt64 nextIndexId; + bool runningVersionChange; nsAutoRefCnt referenceCount; }; diff --git a/dom/indexedDB/IDBDatabase.cpp b/dom/indexedDB/IDBDatabase.cpp index 34c86d40e61..a87a325c75b 100644 --- a/dom/indexedDB/IDBDatabase.cpp +++ b/dom/indexedDB/IDBDatabase.cpp @@ -428,6 +428,34 @@ IDBDatabase::IsClosed() return mClosed; } +void +IDBDatabase::EnterSetVersionTransaction() +{ + DatabaseInfo* dbInfo; + if (!DatabaseInfo::Get(mDatabaseId, &dbInfo)) { + NS_ERROR("This should never fail!"); + } + + NS_ASSERTION(!dbInfo->runningVersionChange, "How did that happen?"); + dbInfo->runningVersionChange = true; +} + +void +IDBDatabase::ExitSetVersionTransaction() +{ + DatabaseInfo* dbInfo; + if (!DatabaseInfo::Get(mDatabaseId, &dbInfo)) { + NS_ERROR("This should never fail!"); + } + + NS_ASSERTION(dbInfo->runningVersionChange, "How did that happen?"); + dbInfo->runningVersionChange = false; + + IndexedDatabaseManager* manager = IndexedDatabaseManager::Get(); + NS_ASSERTION(manager, "We should always have a manager here"); + manager->UnblockSetVersionRunnable(this); +} + void IDBDatabase::OnUnlink() { @@ -710,6 +738,10 @@ IDBDatabase::Transaction(nsIVariant* aStoreNames, NS_ERROR("This should never fail!"); } + if (info->runningVersionChange) { + return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR; + } + nsTArray storesToOpen; switch (type) { diff --git a/dom/indexedDB/IDBDatabase.h b/dom/indexedDB/IDBDatabase.h index 5a2ab7f582e..9df3cb4f3c2 100644 --- a/dom/indexedDB/IDBDatabase.h +++ b/dom/indexedDB/IDBDatabase.h @@ -135,6 +135,9 @@ public: // Whether or not the database has had Close called on it. bool IsClosed(); + void EnterSetVersionTransaction(); + void ExitSetVersionTransaction(); + private: IDBDatabase(); ~IDBDatabase(); diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp index e611fa5676e..baa3784f00a 100644 --- a/dom/indexedDB/IndexedDatabaseManager.cpp +++ b/dom/indexedDB/IndexedDatabaseManager.cpp @@ -693,19 +693,15 @@ IndexedDatabaseManager::OnDatabaseClosed(IDBDatabase* aDatabase) // Now run the helper if there are no more live databases. if (runnable->mHelper && runnable->mDatabases.IsEmpty()) { - // Don't hold the callback alive longer than necessary. - nsRefPtr helper; - helper.swap(runnable->mHelper); + // At this point, all databases are closed, so no new transactions can + // be started. There may, however, still be outstanding transactions + // that have not completed. We need to wait for those before we + // dispatch the helper. - if (NS_FAILED(helper->DispatchToTransactionPool())) { - NS_WARNING("Failed to dispatch to thread pool!"); - } + TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate(); - // Now wait for the transaction to complete. Completing the transaction - // will be our cue to remove the SetVersionRunnable from our list and - // therefore allow other SetVersion requests to begin. - TransactionThreadPool* pool = TransactionThreadPool::Get(); - NS_ASSERTION(pool, "This should never be null!"); + nsRefPtr waitRunnable = + new WaitForTransactionsToFinishRunnable(runnable); // All other databases should be closed, so we only need to wait on this // one. @@ -714,8 +710,8 @@ IndexedDatabaseManager::OnDatabaseClosed(IDBDatabase* aDatabase) NS_ERROR("This should never fail!"); } - // Use the SetVersionRunnable as the callback. - if (!pool->WaitForAllDatabasesToComplete(array, runnable)) { + // Use the WaitForTransactionsToFinishRunnable as the callback. + if (!pool->WaitForAllDatabasesToComplete(array, waitRunnable)) { NS_WARNING("Failed to wait for transaction to complete!"); } } @@ -724,6 +720,27 @@ IndexedDatabaseManager::OnDatabaseClosed(IDBDatabase* aDatabase) } } +void +IndexedDatabaseManager::UnblockSetVersionRunnable(IDBDatabase* aDatabase) +{ + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); + NS_ASSERTION(aDatabase, "Null pointer!"); + + // Check through the list of SetVersionRunnables to find the one we're seeking. + for (PRUint32 index = 0; index < mSetVersionRunnables.Length(); index++) { + nsRefPtr& runnable = mSetVersionRunnables[index]; + + if (runnable->mRequestingDatabase->Id() == aDatabase->Id()) { + NS_ASSERTION(!runnable->mHelper, + "Why are we unblocking a runnable if the helper didn't run?"); + NS_DispatchToCurrentThread(runnable); + return; + } + } + + NS_NOTREACHED("How did we get here!"); +} + // static bool IndexedDatabaseManager::SetCurrentDatabase(IDBDatabase* aDatabase) @@ -1283,3 +1300,39 @@ IndexedDatabaseManager::SetVersionRunnable::Run() return NS_OK; } + +NS_IMPL_THREADSAFE_ISUPPORTS1(IndexedDatabaseManager::WaitForTransactionsToFinishRunnable, + nsIRunnable) + +NS_IMETHODIMP +IndexedDatabaseManager::WaitForTransactionsToFinishRunnable::Run() +{ + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); + + // Don't hold the callback alive longer than necessary. + nsRefPtr helper; + helper.swap(mRunnable->mHelper); + + nsRefPtr runnable; + runnable.swap(mRunnable); + + // If the helper has a transaction, dispatch it to the transaction + // threadpool. + if (helper->HasTransaction()) { + if (NS_FAILED(helper->DispatchToTransactionPool())) { + NS_WARNING("Failed to dispatch to thread pool!"); + } + } + // Otherwise, dispatch it to the IO thread. + else { + IndexedDatabaseManager* manager = IndexedDatabaseManager::Get(); + NS_ASSERTION(manager, "We should definitely have a manager here"); + + helper->Dispatch(manager->IOThread()); + } + + // The helper is responsible for calling + // IndexedDatabaseManager::UnblockSetVersionRunnable. + + return NS_OK; +} diff --git a/dom/indexedDB/IndexedDatabaseManager.h b/dom/indexedDB/IndexedDatabaseManager.h index 853d239482a..7287394d233 100644 --- a/dom/indexedDB/IndexedDatabaseManager.h +++ b/dom/indexedDB/IndexedDatabaseManager.h @@ -204,6 +204,8 @@ private: // Called when AsyncUsageRunnable has finished its Run() method. inline void OnUsageCheckComplete(AsyncUsageRunnable* aRunnable); + void UnblockSetVersionRunnable(IDBDatabase* aDatabase); + // Responsible for waiting until all databases have been closed before running // the version change transaction. Created when // IndexedDatabaseManager::SetDatabaseVersion is called. Runs only once on the @@ -227,6 +229,26 @@ private: // Called when SetVersionRunnable has finished its Run() method. inline void OnSetVersionRunnableComplete(SetVersionRunnable* aRunnable); + + // A callback runnable used by the TransactionPool when it's safe to proceed + // with a SetVersion/DeleteDatabase/etc. + class WaitForTransactionsToFinishRunnable : public nsIRunnable + { + public: + WaitForTransactionsToFinishRunnable(SetVersionRunnable* aRunnable) + : mRunnable(aRunnable) + { + NS_ASSERTION(mRunnable, "Why don't we have a runnable?"); + NS_ASSERTION(mRunnable->mDatabases.IsEmpty(), "We're here too early!"); + } + + NS_DECL_ISUPPORTS + NS_DECL_NSIRUNNABLE + + private: + nsRefPtr mRunnable; + }; + // Maintains a list of live databases per origin. nsClassHashtable > mLiveDatabases; diff --git a/dom/indexedDB/OpenDatabaseHelper.cpp b/dom/indexedDB/OpenDatabaseHelper.cpp index 7e7559b47c8..cc909fec4d5 100644 --- a/dom/indexedDB/OpenDatabaseHelper.cpp +++ b/dom/indexedDB/OpenDatabaseHelper.cpp @@ -495,10 +495,13 @@ public: NS_DECL_ISUPPORTS_INHERITED - nsresult DoDatabaseWork(mozIStorageConnection* aConnection); nsresult GetSuccessResult(JSContext* aCx, jsval* aVal); +protected: + nsresult DoDatabaseWork(mozIStorageConnection* aConnection); + nsresult Init(); + // SetVersionHelper never fires an error event at the request. It hands that // responsibility back to the OpenDatabaseHelper void OnError() { } @@ -684,6 +687,7 @@ OpenDatabaseHelper::StartSetVersion() // The SetVersionHelper is responsible for dispatching us back to the // main thread again and changing the state to eSetVersionCompleted. mState = eSetVersionPending; + return NS_OK; } @@ -711,6 +715,12 @@ OpenDatabaseHelper::Run() mState == eSetVersionCompleted, "Why are we here?"); if (mState == eSetVersionCompleted) { + // Allow transaction creation/other version change transactions to proceed + // before we fire events. Other version changes will be postd to the end + // of the event loop, and will be behind whatever the page does in + // its error/success event handlers. + mDatabase->ExitSetVersionTransaction(); + mState = eFiringEvents; } else { // Notify the request that we're done, but only if we didn't just finish @@ -865,6 +875,15 @@ OpenDatabaseHelper::NotifySetVersionFinished() return NS_DispatchToCurrentThread(this); } +void +OpenDatabaseHelper::BlockDatabase() +{ + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); + NS_ASSERTION(mDatabase, "This is going bad fast."); + + mDatabase->EnterSetVersionTransaction(); +} + void OpenDatabaseHelper::DispatchSuccessEvent() { @@ -916,6 +935,15 @@ OpenDatabaseHelper::ReleaseMainThreadObjects() NS_IMPL_ISUPPORTS_INHERITED0(SetVersionHelper, AsyncConnectionHelper); +nsresult +SetVersionHelper::Init() +{ + // Block transaction creation until we are done. + mOpenHelper->BlockDatabase(); + + return NS_OK; +} + nsresult SetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection) { diff --git a/dom/indexedDB/OpenDatabaseHelper.h b/dom/indexedDB/OpenDatabaseHelper.h index 0d91db6b2dc..53334867ab3 100644 --- a/dom/indexedDB/OpenDatabaseHelper.h +++ b/dom/indexedDB/OpenDatabaseHelper.h @@ -82,6 +82,7 @@ public: } nsresult NotifySetVersionFinished(); + void BlockDatabase(); protected: // Methods only called on the main thread diff --git a/dom/indexedDB/TransactionThreadPool.cpp b/dom/indexedDB/TransactionThreadPool.cpp index 2bb66132b48..c78ba97ef90 100644 --- a/dom/indexedDB/TransactionThreadPool.cpp +++ b/dom/indexedDB/TransactionThreadPool.cpp @@ -238,7 +238,6 @@ TransactionThreadPool::FinishTransaction(IDBTransaction* aTransaction) #ifdef DEBUG if (aTransaction->mMode == IDBTransaction::VERSION_CHANGE) { - NS_ASSERTION(dbTransactionInfo->locked, "Should be locked!"); NS_ASSERTION(transactionCount == 1, "More transactions running than should be!"); } @@ -344,10 +343,6 @@ TransactionThreadPool::TransactionCanRun(IDBTransaction* aTransaction, PRUint32 transactionCount = transactionsInProgress.Length(); NS_ASSERTION(transactionCount, "Should never be 0!"); - if (mode == IDBTransaction::VERSION_CHANGE) { - dbTransactionInfo->lockPending = true; - } - for (PRUint32 index = 0; index < transactionCount; index++) { // See if this transaction is in out list of current transactions. const TransactionInfo& info = transactionsInProgress[index]; @@ -358,11 +353,7 @@ TransactionThreadPool::TransactionCanRun(IDBTransaction* aTransaction, } } - if (dbTransactionInfo->locked || dbTransactionInfo->lockPending) { - *aCanRun = false; - *aExistingQueue = nsnull; - return NS_OK; - } + NS_ASSERTION(mode != IDBTransaction::VERSION_CHANGE, "How did we get here?"); bool writeOverlap; nsresult rv = @@ -448,11 +439,6 @@ TransactionThreadPool::Dispatch(IDBTransaction* aTransaction, dbTransactionInfo = autoDBTransactionInfo; } - if (aTransaction->mMode == IDBTransaction::VERSION_CHANGE) { - NS_ASSERTION(!dbTransactionInfo->locked, "Already locked?!"); - dbTransactionInfo->locked = true; - } - const nsTArray& objectStoreNames = aTransaction->mObjectStoreNames; nsTArray& storesInUse = diff --git a/dom/indexedDB/TransactionThreadPool.h b/dom/indexedDB/TransactionThreadPool.h index 97d15c46917..4fdd152c4b0 100644 --- a/dom/indexedDB/TransactionThreadPool.h +++ b/dom/indexedDB/TransactionThreadPool.h @@ -123,12 +123,6 @@ protected: struct DatabaseTransactionInfo { - DatabaseTransactionInfo() - : locked(false), lockPending(false) - { } - - bool locked; - bool lockPending; nsTArray transactions; nsTArray storesReading; nsTArray storesWriting; diff --git a/dom/indexedDB/test/Makefile.in b/dom/indexedDB/test/Makefile.in index 555fbeaf93f..9d7d00f15f6 100644 --- a/dom/indexedDB/test/Makefile.in +++ b/dom/indexedDB/test/Makefile.in @@ -98,6 +98,7 @@ TEST_FILES = \ test_setVersion.html \ test_setVersion_abort.html \ test_setVersion_events.html \ + test_setVersion_exclusion.html \ test_writer_starvation.html \ third_party_iframe1.html \ third_party_iframe2.html \ diff --git a/dom/indexedDB/test/event_propagation_iframe.html b/dom/indexedDB/test/event_propagation_iframe.html index 2d1f745fad5..035fa86248a 100644 --- a/dom/indexedDB/test/event_propagation_iframe.html +++ b/dom/indexedDB/test/event_propagation_iframe.html @@ -104,7 +104,7 @@ db.onerror = errorEventCounter; db.addEventListener("error", errorEventCounter, true); - event.target.transaction.oncomplete = grabEventAndContinueHandler; + event.target.onsuccess = grabEventAndContinueHandler; db.createObjectStore("foo", { autoIncrement: true }); yield; diff --git a/dom/indexedDB/test/leaving_page_iframe.html b/dom/indexedDB/test/leaving_page_iframe.html index 43d0e00ab98..00bcff71243 100644 --- a/dom/indexedDB/test/leaving_page_iframe.html +++ b/dom/indexedDB/test/leaving_page_iframe.html @@ -12,7 +12,7 @@ function startDBWork() { } var store = db.createObjectStore("mystore"); store.add({ hello: "world" }, 42); - trans.oncomplete = madeMod; + e.target.onsuccess = madeMod; }; } diff --git a/dom/indexedDB/test/test_autoIncrement_indexes.html b/dom/indexedDB/test/test_autoIncrement_indexes.html index b24d4896c9d..951be60eef9 100644 --- a/dom/indexedDB/test/test_autoIncrement_indexes.html +++ b/dom/indexedDB/test/test_autoIncrement_indexes.html @@ -33,6 +33,9 @@ let key = event.target.result; ok(key, "Added entry"); + request.onsuccess = grabEventAndContinueHandler; + + event = yield; let objectStore = db.transaction("foo").objectStore("foo"); let first = objectStore.index("first"); diff --git a/dom/indexedDB/test/test_clear.html b/dom/indexedDB/test/test_clear.html index 648f234dafd..44f85569357 100644 --- a/dom/indexedDB/test/test_clear.html +++ b/dom/indexedDB/test/test_clear.html @@ -25,7 +25,7 @@ let db = request.result; - event.target.transaction.oncomplete = continueToNextStep; + event.target.onsuccess = continueToNextStep; let objectStore = db.createObjectStore("foo", { autoIncrement: true }); diff --git a/dom/indexedDB/test/test_create_index_with_integer_keys.html b/dom/indexedDB/test/test_create_index_with_integer_keys.html index 37c3d601656..6b058ce6b9c 100644 --- a/dom/indexedDB/test/test_create_index_with_integer_keys.html +++ b/dom/indexedDB/test/test_create_index_with_integer_keys.html @@ -23,7 +23,7 @@ let db = event.target.result; db.onerror = errorHandler; - event.target.transaction.oncomplete = continueToNextStep; + event.target.onsuccess = continueToNextStep; // Make object store, add data. let objectStore = db.createObjectStore("foo", { keyPath: "id" }); @@ -39,7 +39,7 @@ let db2 = event.target.result; db2.onerror = errorHandler; - event.target.transaction.oncomplete = continueToNextStep; + event.target.onsuccess = continueToNextStep; // Create index. event.target.transaction.objectStore("foo").createIndex("foo", "num"); diff --git a/dom/indexedDB/test/test_cursor_mutation.html b/dom/indexedDB/test/test_cursor_mutation.html index 7812c1f2ec9..c3d6e52a3ec 100644 --- a/dom/indexedDB/test/test_cursor_mutation.html +++ b/dom/indexedDB/test/test_cursor_mutation.html @@ -35,7 +35,7 @@ let event = yield; let db = event.target.result; - event.target.transaction.oncomplete = continueToNextStep; + event.target.onsuccess = continueToNextStep; let objectStore = db.createObjectStore("foo", { keyPath: "ss" }); objectStore.createIndex("name", "name", { unique: true }); diff --git a/dom/indexedDB/test/test_getAll.html b/dom/indexedDB/test/test_getAll.html index 3c873efdfde..7f76c438531 100644 --- a/dom/indexedDB/test/test_getAll.html +++ b/dom/indexedDB/test/test_getAll.html @@ -26,6 +26,7 @@ let objectStore = db.createObjectStore("foo", { autoIncrement: true }); + request.onsuccess = grabEventAndContinueHandler; request = objectStore.getAll(); request.onerror = errorHandler; request.onsuccess = grabEventAndContinueHandler; @@ -46,6 +47,7 @@ } } yield; + yield; request = db.transaction("foo").objectStore("foo").getAll(); request.onerror = errorHandler; diff --git a/dom/indexedDB/test/test_index_getAll.html b/dom/indexedDB/test/test_index_getAll.html index 584bb9ff3e3..ba9fa0067a0 100644 --- a/dom/indexedDB/test/test_index_getAll.html +++ b/dom/indexedDB/test/test_index_getAll.html @@ -60,6 +60,7 @@ let request = mozIndexedDB.open(name, 1, description); request.onerror = errorHandler; request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = grabEventAndContinueHandler; let event = yield; let db = event.target.result; @@ -78,7 +79,7 @@ } } } - event = yield; + yield; ok(true, "1"); // Now create the indexes. @@ -88,7 +89,6 @@ } is(objectStore.indexNames.length, indexData.length, "Good index count"); - continueToNextStep(); yield; ok(true, "2"); diff --git a/dom/indexedDB/test/test_index_getAllObjects.html b/dom/indexedDB/test/test_index_getAllObjects.html index a65a0536945..585a0d117ac 100644 --- a/dom/indexedDB/test/test_index_getAllObjects.html +++ b/dom/indexedDB/test/test_index_getAllObjects.html @@ -60,6 +60,7 @@ let request = mozIndexedDB.open(name, 1, description); request.onerror = errorHandler; request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = grabEventAndContinueHandler; let event = yield; let db = event.target.result; @@ -87,7 +88,6 @@ } is(objectStore.indexNames.length, indexData.length, "Good index count"); - continueToNextStep(); yield; objectStore = db.transaction(objectStoreName) diff --git a/dom/indexedDB/test/test_index_object_cursors.html b/dom/indexedDB/test/test_index_object_cursors.html index b7091206d5d..fb8228e2ca1 100644 --- a/dom/indexedDB/test/test_index_object_cursors.html +++ b/dom/indexedDB/test/test_index_object_cursors.html @@ -37,7 +37,7 @@ let db = event.target.result; db.onerror = errorHandler; - event.target.transaction.oncomplete = continueToNextStep; + event.target.onsuccess = continueToNextStep; for (let objectStoreIndex in objectStoreData) { const objectStoreInfo = objectStoreData[objectStoreIndex]; diff --git a/dom/indexedDB/test/test_indexes.html b/dom/indexedDB/test/test_indexes.html index 05132a87d22..98e33701ae6 100644 --- a/dom/indexedDB/test/test_indexes.html +++ b/dom/indexedDB/test/test_indexes.html @@ -71,6 +71,7 @@ let request = mozIndexedDB.open(name, 1, description); request.onerror = errorHandler; request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = grabEventAndContinueHandler; let event = yield; let db = event.target.result; @@ -97,7 +98,6 @@ indexData[i].options); } is(objectStore.indexNames.length, indexData.length, "Good index count"); - continueToNextStep(); yield; objectStore = db.transaction(objectStoreName) diff --git a/dom/indexedDB/test/test_indexes_bad_values.html b/dom/indexedDB/test/test_indexes_bad_values.html index e28aa6dd718..ffb92160868 100644 --- a/dom/indexedDB/test/test_indexes_bad_values.html +++ b/dom/indexedDB/test/test_indexes_bad_values.html @@ -51,6 +51,7 @@ let request = mozIndexedDB.open(name, 1, description); request.onerror = errorHandler; request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = grabEventAndContinueHandler; let event = yield; let db = event.target.result; @@ -87,6 +88,7 @@ } } yield; + yield; objectStore = db.transaction(objectStoreName) .objectStore(objectStoreName); diff --git a/dom/indexedDB/test/test_object_identity.html b/dom/indexedDB/test/test_object_identity.html index 211725d3055..600bc396cdd 100644 --- a/dom/indexedDB/test/test_object_identity.html +++ b/dom/indexedDB/test/test_object_identity.html @@ -28,7 +28,7 @@ let index2 = objectStore2.index("bar"); ok(index1 === index2, "Got same indexes"); - transaction.oncomplete = continueToNextStep; + request.onsuccess = continueToNextStep; yield; transaction = db.transaction("foo"); diff --git a/dom/indexedDB/test/test_odd_result_order.html b/dom/indexedDB/test/test_odd_result_order.html index 2a127e6b832..1d14fcf66ce 100644 --- a/dom/indexedDB/test/test_odd_result_order.html +++ b/dom/indexedDB/test/test_odd_result_order.html @@ -29,7 +29,7 @@ autoIncrement: true }); let index = objectStore.createIndex("foo", "index"); - event.target.transaction.oncomplete = continueToNextStep; + event.target.onsuccess = continueToNextStep; yield; objectStore = db.transaction("foo", IDBTransaction.READ_WRITE) diff --git a/dom/indexedDB/test/test_open_objectStore.html b/dom/indexedDB/test/test_open_objectStore.html index 93f09ee1e76..48ece9f2af5 100644 --- a/dom/indexedDB/test/test_open_objectStore.html +++ b/dom/indexedDB/test/test_open_objectStore.html @@ -20,6 +20,7 @@ let request = mozIndexedDB.open(name, 1, description); request.onerror = errorHandler; request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = grabEventAndContinueHandler; let event = yield; let db = event.target.result; @@ -31,7 +32,6 @@ is(db.objectStoreNames.length, 1, "Bad objectStores list"); is(db.objectStoreNames.item(0), objectStoreName, "Bad name"); - continueToNextStep(); yield; objectStore = db.transaction(objectStoreName).objectStore(objectStoreName); diff --git a/dom/indexedDB/test/test_overlapping_transactions.html b/dom/indexedDB/test/test_overlapping_transactions.html index b59f60f3fe4..39746ce8a37 100644 --- a/dom/indexedDB/test/test_overlapping_transactions.html +++ b/dom/indexedDB/test/test_overlapping_transactions.html @@ -26,7 +26,7 @@ let db = event.target.result; is(db.objectStoreNames.length, 0, "Correct objectStoreNames list"); - event.target.transaction.oncomplete = grabEventAndContinueHandler; + event.target.onsuccess = grabEventAndContinueHandler; for (let i in objectStores) { db.createObjectStore(objectStores[i], { autoIncrement: true }); } diff --git a/dom/indexedDB/test/test_readonly_transactions.html b/dom/indexedDB/test/test_readonly_transactions.html index 5987a1c35f1..58a0a8ad9e3 100644 --- a/dom/indexedDB/test/test_readonly_transactions.html +++ b/dom/indexedDB/test/test_readonly_transactions.html @@ -22,6 +22,7 @@ let request = mozIndexedDB.open(name, 1, description); request.onerror = errorHandler; request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = grabEventAndContinueHandler; let event = yield; let db = event.target.result; @@ -29,6 +30,8 @@ db.createObjectStore(osName, { autoIncrement: "true" }); + yield; + let key1, key2; request = db.transaction([osName], READ_WRITE) diff --git a/dom/indexedDB/test/test_setVersion_exclusion.html b/dom/indexedDB/test/test_setVersion_exclusion.html new file mode 100644 index 00000000000..96d0d322c28 --- /dev/null +++ b/dom/indexedDB/test/test_setVersion_exclusion.html @@ -0,0 +1,90 @@ + + + + Indexed Database Property Test + + + + + + + + + + + + diff --git a/dom/indexedDB/test/test_success_events_after_abort.html b/dom/indexedDB/test/test_success_events_after_abort.html index c9d75a4cb78..31a29d59d56 100644 --- a/dom/indexedDB/test/test_success_events_after_abort.html +++ b/dom/indexedDB/test/test_success_events_after_abort.html @@ -19,7 +19,7 @@ let db = event.target.result; - event.target.transaction.oncomplete = continueToNextStep; + event.target.onsuccess = continueToNextStep; let objectStore = db.createObjectStore("foo"); objectStore.add({}, 1).onerror = errorHandler; diff --git a/dom/indexedDB/test/test_transaction_abort.html b/dom/indexedDB/test/test_transaction_abort.html index 9558212a9a3..e7d6906c202 100644 --- a/dom/indexedDB/test/test_transaction_abort.html +++ b/dom/indexedDB/test/test_transaction_abort.html @@ -29,6 +29,7 @@ let request = mozIndexedDB.open(name, 1, description); request.onerror = errorHandler; request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = grabEventAndContinueHandler; let event = yield; let db = event.target.result; @@ -157,6 +158,8 @@ ok(true, "RemoveIndex threw"); } + yield; + request = db.transaction("foo", READ_WRITE).objectStore("foo").add({}); request.onerror = errorHandler; request.onsuccess = grabEventAndContinueHandler; diff --git a/dom/indexedDB/test/test_transaction_lifetimes.html b/dom/indexedDB/test/test_transaction_lifetimes.html index c402ec8b81d..7e9e2e368bd 100644 --- a/dom/indexedDB/test/test_transaction_lifetimes.html +++ b/dom/indexedDB/test/test_transaction_lifetimes.html @@ -20,7 +20,7 @@ let db = event.target.result; db.onerror = errorHandler; - event.target.transaction.oncomplete = continueToNextStep; + event.target.onsuccess = continueToNextStep; db.createObjectStore("foo", { autoIncrement: true }); yield; diff --git a/dom/indexedDB/test/test_transaction_lifetimes_nested.html b/dom/indexedDB/test/test_transaction_lifetimes_nested.html index de7b1cebc74..2fde9b81dd5 100644 --- a/dom/indexedDB/test/test_transaction_lifetimes_nested.html +++ b/dom/indexedDB/test/test_transaction_lifetimes_nested.html @@ -20,7 +20,7 @@ let db = event.target.result; db.onerror = errorHandler; - event.target.transaction.oncomplete = continueToNextStep; + event.target.onsuccess = continueToNextStep; db.createObjectStore("foo"); yield; diff --git a/dom/indexedDB/test/test_writer_starvation.html b/dom/indexedDB/test/test_writer_starvation.html index d29bdf8bb5f..456975bcca9 100644 --- a/dom/indexedDB/test/test_writer_starvation.html +++ b/dom/indexedDB/test/test_writer_starvation.html @@ -23,6 +23,7 @@ let request = mozIndexedDB.open(name, 1, description); request.onerror = errorHandler; request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = grabEventAndContinueHandler; let event = yield; let db = event.target.result; @@ -39,7 +40,6 @@ let key = event.target.result; ok(key, "Got a key"); - SimpleTest.executeSoon(function() { testGenerator.next(); }); yield; let continueReading = true;