LCOV - code coverage report
Current view: top level - dom/indexedDB - IDBTransaction.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 498 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 49 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "IDBTransaction.h"
       8             : 
       9             : #include "BackgroundChildImpl.h"
      10             : #include "IDBDatabase.h"
      11             : #include "IDBEvents.h"
      12             : #include "IDBObjectStore.h"
      13             : #include "IDBRequest.h"
      14             : #include "mozilla/ErrorResult.h"
      15             : #include "mozilla/EventDispatcher.h"
      16             : #include "mozilla/dom/DOMError.h"
      17             : #include "mozilla/dom/DOMStringList.h"
      18             : #include "mozilla/ipc/BackgroundChild.h"
      19             : #include "nsAutoPtr.h"
      20             : #include "nsPIDOMWindow.h"
      21             : #include "nsQueryObject.h"
      22             : #include "nsServiceManagerUtils.h"
      23             : #include "nsTHashtable.h"
      24             : #include "ProfilerHelpers.h"
      25             : #include "ReportInternalError.h"
      26             : #include "WorkerHolder.h"
      27             : #include "WorkerPrivate.h"
      28             : 
      29             : // Include this last to avoid path problems on Windows.
      30             : #include "ActorsChild.h"
      31             : 
      32             : namespace mozilla {
      33             : namespace dom {
      34             : 
      35             : using namespace mozilla::dom::indexedDB;
      36             : using namespace mozilla::dom::workers;
      37             : using namespace mozilla::ipc;
      38             : 
      39             : class IDBTransaction::WorkerHolder final
      40             :   : public mozilla::dom::workers::WorkerHolder
      41             : {
      42             :   WorkerPrivate* mWorkerPrivate;
      43             : 
      44             :   // The IDBTransaction owns this object so we only need a weak reference back
      45             :   // to it.
      46             :   IDBTransaction* mTransaction;
      47             : 
      48             : public:
      49           0 :   WorkerHolder(WorkerPrivate* aWorkerPrivate, IDBTransaction* aTransaction)
      50           0 :     : mWorkerPrivate(aWorkerPrivate)
      51           0 :     , mTransaction(aTransaction)
      52             :   {
      53           0 :     MOZ_ASSERT(aWorkerPrivate);
      54           0 :     MOZ_ASSERT(aTransaction);
      55           0 :     aWorkerPrivate->AssertIsOnWorkerThread();
      56           0 :     aTransaction->AssertIsOnOwningThread();
      57             : 
      58           0 :     MOZ_COUNT_CTOR(IDBTransaction::WorkerHolder);
      59           0 :   }
      60             : 
      61           0 :   ~WorkerHolder()
      62           0 :   {
      63           0 :     mWorkerPrivate->AssertIsOnWorkerThread();
      64             : 
      65           0 :     MOZ_COUNT_DTOR(IDBTransaction::WorkerHolder);
      66           0 :   }
      67             : 
      68             : private:
      69             :   virtual bool
      70             :   Notify(Status aStatus) override;
      71             : };
      72             : 
      73           0 : IDBTransaction::IDBTransaction(IDBDatabase* aDatabase,
      74             :                                const nsTArray<nsString>& aObjectStoreNames,
      75           0 :                                Mode aMode)
      76             :   : IDBWrapperCache(aDatabase)
      77             :   , mDatabase(aDatabase)
      78             :   , mObjectStoreNames(aObjectStoreNames)
      79             :   , mLoggingSerialNumber(0)
      80             :   , mNextObjectStoreId(0)
      81             :   , mNextIndexId(0)
      82             :   , mAbortCode(NS_OK)
      83             :   , mPendingRequestCount(0)
      84             :   , mLineNo(0)
      85             :   , mColumn(0)
      86             :   , mReadyState(IDBTransaction::INITIAL)
      87             :   , mMode(aMode)
      88             :   , mCreating(false)
      89             :   , mRegistered(false)
      90             :   , mAbortedByScript(false)
      91             :   , mNotedActiveTransaction(false)
      92             : #ifdef DEBUG
      93             :   , mSentCommitOrAbort(false)
      94           0 :   , mFiredCompleteOrAbort(false)
      95             : #endif
      96             : {
      97           0 :   MOZ_ASSERT(aDatabase);
      98           0 :   aDatabase->AssertIsOnOwningThread();
      99             : 
     100           0 :   mBackgroundActor.mNormalBackgroundActor = nullptr;
     101             : 
     102             :   BackgroundChildImpl::ThreadLocal* threadLocal =
     103           0 :     BackgroundChildImpl::GetThreadLocalForCurrentThread();
     104           0 :   MOZ_ASSERT(threadLocal);
     105             : 
     106           0 :   ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
     107           0 :   MOZ_ASSERT(idbThreadLocal);
     108             : 
     109           0 :   const_cast<int64_t&>(mLoggingSerialNumber) =
     110           0 :     idbThreadLocal->NextTransactionSN(aMode);
     111             : 
     112             : #ifdef DEBUG
     113           0 :   if (!aObjectStoreNames.IsEmpty()) {
     114           0 :     nsTArray<nsString> sortedNames(aObjectStoreNames);
     115           0 :     sortedNames.Sort();
     116             : 
     117           0 :     const uint32_t count = sortedNames.Length();
     118           0 :     MOZ_ASSERT(count == aObjectStoreNames.Length());
     119             : 
     120             :     // Make sure the array is properly sorted.
     121           0 :     for (uint32_t index = 0; index < count; index++) {
     122           0 :       MOZ_ASSERT(aObjectStoreNames[index] == sortedNames[index]);
     123             :     }
     124             : 
     125             :     // Make sure there are no duplicates in our objectStore names.
     126           0 :     for (uint32_t index = 0; index < count - 1; index++) {
     127           0 :       MOZ_ASSERT(sortedNames[index] != sortedNames[index + 1]);
     128             :     }
     129             :   }
     130             : #endif
     131           0 : }
     132             : 
     133           0 : IDBTransaction::~IDBTransaction()
     134             : {
     135           0 :   AssertIsOnOwningThread();
     136           0 :   MOZ_ASSERT(!mPendingRequestCount);
     137           0 :   MOZ_ASSERT(!mCreating);
     138           0 :   MOZ_ASSERT(!mNotedActiveTransaction);
     139           0 :   MOZ_ASSERT(mSentCommitOrAbort);
     140           0 :   MOZ_ASSERT_IF(mMode == VERSION_CHANGE &&
     141             :                   mBackgroundActor.mVersionChangeBackgroundActor,
     142             :                 mFiredCompleteOrAbort);
     143           0 :   MOZ_ASSERT_IF(mMode != VERSION_CHANGE &&
     144             :                   mBackgroundActor.mNormalBackgroundActor,
     145             :                 mFiredCompleteOrAbort);
     146             : 
     147           0 :   if (mRegistered) {
     148           0 :     mDatabase->UnregisterTransaction(this);
     149             : #ifdef DEBUG
     150           0 :     mRegistered = false;
     151             : #endif
     152             :   }
     153             : 
     154           0 :   if (mMode == VERSION_CHANGE) {
     155           0 :     if (auto* actor = mBackgroundActor.mVersionChangeBackgroundActor) {
     156           0 :       actor->SendDeleteMeInternal(/* aFailedConstructor */ false);
     157             : 
     158           0 :       MOZ_ASSERT(!mBackgroundActor.mVersionChangeBackgroundActor,
     159             :                  "SendDeleteMeInternal should have cleared!");
     160             :     }
     161           0 :   } else if (auto* actor = mBackgroundActor.mNormalBackgroundActor) {
     162           0 :     actor->SendDeleteMeInternal();
     163             : 
     164           0 :     MOZ_ASSERT(!mBackgroundActor.mNormalBackgroundActor,
     165             :                "SendDeleteMeInternal should have cleared!");
     166             :   }
     167           0 : }
     168             : 
     169             : // static
     170             : already_AddRefed<IDBTransaction>
     171           0 : IDBTransaction::CreateVersionChange(
     172             :                                 IDBDatabase* aDatabase,
     173             :                                 BackgroundVersionChangeTransactionChild* aActor,
     174             :                                 IDBOpenDBRequest* aOpenRequest,
     175             :                                 int64_t aNextObjectStoreId,
     176             :                                 int64_t aNextIndexId)
     177             : {
     178           0 :   MOZ_ASSERT(aDatabase);
     179           0 :   aDatabase->AssertIsOnOwningThread();
     180           0 :   MOZ_ASSERT(aActor);
     181           0 :   MOZ_ASSERT(aOpenRequest);
     182           0 :   MOZ_ASSERT(aNextObjectStoreId > 0);
     183           0 :   MOZ_ASSERT(aNextIndexId > 0);
     184             : 
     185           0 :   nsTArray<nsString> emptyObjectStoreNames;
     186             : 
     187             :   RefPtr<IDBTransaction> transaction =
     188             :     new IDBTransaction(aDatabase,
     189             :                        emptyObjectStoreNames,
     190           0 :                        VERSION_CHANGE);
     191           0 :   aOpenRequest->GetCallerLocation(transaction->mFilename,
     192           0 :                                   &transaction->mLineNo, &transaction->mColumn);
     193             : 
     194           0 :   transaction->SetScriptOwner(aDatabase->GetScriptOwner());
     195             : 
     196           0 :   nsCOMPtr<nsIRunnable> runnable = do_QueryObject(transaction);
     197           0 :   nsContentUtils::RunInMetastableState(runnable.forget());
     198             : 
     199           0 :   transaction->NoteActiveTransaction();
     200             : 
     201           0 :   transaction->mBackgroundActor.mVersionChangeBackgroundActor = aActor;
     202           0 :   transaction->mNextObjectStoreId = aNextObjectStoreId;
     203           0 :   transaction->mNextIndexId = aNextIndexId;
     204           0 :   transaction->mCreating = true;
     205             : 
     206           0 :   aDatabase->RegisterTransaction(transaction);
     207           0 :   transaction->mRegistered = true;
     208             : 
     209           0 :   return transaction.forget();
     210             : }
     211             : 
     212             : // static
     213             : already_AddRefed<IDBTransaction>
     214           0 : IDBTransaction::Create(JSContext* aCx, IDBDatabase* aDatabase,
     215             :                        const nsTArray<nsString>& aObjectStoreNames,
     216             :                        Mode aMode)
     217             : {
     218           0 :   MOZ_ASSERT(aDatabase);
     219           0 :   aDatabase->AssertIsOnOwningThread();
     220           0 :   MOZ_ASSERT(!aObjectStoreNames.IsEmpty());
     221           0 :   MOZ_ASSERT(aMode == READ_ONLY ||
     222             :              aMode == READ_WRITE ||
     223             :              aMode == READ_WRITE_FLUSH ||
     224             :              aMode == CLEANUP);
     225             : 
     226             :   RefPtr<IDBTransaction> transaction =
     227           0 :     new IDBTransaction(aDatabase, aObjectStoreNames, aMode);
     228           0 :   IDBRequest::CaptureCaller(aCx, transaction->mFilename, &transaction->mLineNo,
     229           0 :                             &transaction->mColumn);
     230             : 
     231           0 :   transaction->SetScriptOwner(aDatabase->GetScriptOwner());
     232             : 
     233           0 :   nsCOMPtr<nsIRunnable> runnable = do_QueryObject(transaction);
     234           0 :   nsContentUtils::RunInMetastableState(runnable.forget());
     235             : 
     236           0 :   transaction->mCreating = true;
     237             : 
     238           0 :   aDatabase->RegisterTransaction(transaction);
     239           0 :   transaction->mRegistered = true;
     240             : 
     241           0 :   if (!NS_IsMainThread()) {
     242           0 :     WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     243           0 :     MOZ_ASSERT(workerPrivate);
     244             : 
     245           0 :     workerPrivate->AssertIsOnWorkerThread();
     246             : 
     247           0 :     transaction->mWorkerHolder = new WorkerHolder(workerPrivate, transaction);
     248           0 :     MOZ_ALWAYS_TRUE(transaction->mWorkerHolder->HoldWorker(workerPrivate, Canceling));
     249             :   }
     250             : 
     251           0 :   return transaction.forget();
     252             : }
     253             : 
     254             : // static
     255             : IDBTransaction*
     256           0 : IDBTransaction::GetCurrent()
     257             : {
     258             :   using namespace mozilla::ipc;
     259             : 
     260           0 :   MOZ_ASSERT(BackgroundChild::GetForCurrentThread());
     261             : 
     262             :   BackgroundChildImpl::ThreadLocal* threadLocal =
     263           0 :     BackgroundChildImpl::GetThreadLocalForCurrentThread();
     264           0 :   MOZ_ASSERT(threadLocal);
     265             : 
     266           0 :   ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
     267           0 :   MOZ_ASSERT(idbThreadLocal);
     268             : 
     269           0 :   return idbThreadLocal->GetCurrentTransaction();
     270             : }
     271             : 
     272             : #ifdef DEBUG
     273             : 
     274             : void
     275           0 : IDBTransaction::AssertIsOnOwningThread() const
     276             : {
     277           0 :   MOZ_ASSERT(mDatabase);
     278           0 :   mDatabase->AssertIsOnOwningThread();
     279           0 : }
     280             : 
     281             : #endif // DEBUG
     282             : 
     283             : void
     284           0 : IDBTransaction::SetBackgroundActor(indexedDB::BackgroundTransactionChild* aBackgroundActor)
     285             : {
     286           0 :   AssertIsOnOwningThread();
     287           0 :   MOZ_ASSERT(aBackgroundActor);
     288           0 :   MOZ_ASSERT(!mBackgroundActor.mNormalBackgroundActor);
     289           0 :   MOZ_ASSERT(mMode != VERSION_CHANGE);
     290             : 
     291           0 :   NoteActiveTransaction();
     292             : 
     293           0 :   mBackgroundActor.mNormalBackgroundActor = aBackgroundActor;
     294           0 : }
     295             : 
     296             : BackgroundRequestChild*
     297           0 : IDBTransaction::StartRequest(IDBRequest* aRequest, const RequestParams& aParams)
     298             : {
     299           0 :   AssertIsOnOwningThread();
     300           0 :   MOZ_ASSERT(aRequest);
     301           0 :   MOZ_ASSERT(aParams.type() != RequestParams::T__None);
     302             : 
     303           0 :   BackgroundRequestChild* actor = new BackgroundRequestChild(aRequest);
     304             : 
     305           0 :   if (mMode == VERSION_CHANGE) {
     306           0 :     MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
     307             : 
     308           0 :     mBackgroundActor.mVersionChangeBackgroundActor->
     309           0 :       SendPBackgroundIDBRequestConstructor(actor, aParams);
     310             :   } else {
     311           0 :     MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
     312             : 
     313           0 :     mBackgroundActor.mNormalBackgroundActor->
     314           0 :       SendPBackgroundIDBRequestConstructor(actor, aParams);
     315             :   }
     316             : 
     317           0 :   MOZ_ASSERT(actor->GetActorEventTarget(),
     318             :     "The event target shall be inherited from its manager actor.");
     319             : 
     320             :   // Balanced in BackgroundRequestChild::Recv__delete__().
     321           0 :   OnNewRequest();
     322             : 
     323           0 :   return actor;
     324             : }
     325             : 
     326             : void
     327           0 : IDBTransaction::OpenCursor(BackgroundCursorChild* aBackgroundActor,
     328             :                            const OpenCursorParams& aParams)
     329             : {
     330           0 :   AssertIsOnOwningThread();
     331           0 :   MOZ_ASSERT(aBackgroundActor);
     332           0 :   MOZ_ASSERT(aParams.type() != OpenCursorParams::T__None);
     333             : 
     334           0 :   if (mMode == VERSION_CHANGE) {
     335           0 :     MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
     336             : 
     337           0 :     mBackgroundActor.mVersionChangeBackgroundActor->
     338           0 :       SendPBackgroundIDBCursorConstructor(aBackgroundActor, aParams);
     339             :   } else {
     340           0 :     MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
     341             : 
     342           0 :     mBackgroundActor.mNormalBackgroundActor->
     343           0 :       SendPBackgroundIDBCursorConstructor(aBackgroundActor, aParams);
     344             :   }
     345             : 
     346           0 :   MOZ_ASSERT(aBackgroundActor->GetActorEventTarget(),
     347             :     "The event target shall be inherited from its manager actor.");
     348             : 
     349             :   // Balanced in BackgroundCursorChild::RecvResponse().
     350           0 :   OnNewRequest();
     351           0 : }
     352             : 
     353             : void
     354           0 : IDBTransaction::RefreshSpec(bool aMayDelete)
     355             : {
     356           0 :   AssertIsOnOwningThread();
     357             : 
     358           0 :   for (uint32_t count = mObjectStores.Length(), index = 0;
     359           0 :        index < count;
     360             :        index++) {
     361           0 :     mObjectStores[index]->RefreshSpec(aMayDelete);
     362             :   }
     363             : 
     364           0 :   for (uint32_t count = mDeletedObjectStores.Length(), index = 0;
     365           0 :        index < count;
     366             :        index++) {
     367           0 :     mDeletedObjectStores[index]->RefreshSpec(false);
     368             :   }
     369           0 : }
     370             : 
     371             : void
     372           0 : IDBTransaction::OnNewRequest()
     373             : {
     374           0 :   AssertIsOnOwningThread();
     375             : 
     376           0 :   if (!mPendingRequestCount) {
     377           0 :     MOZ_ASSERT(INITIAL == mReadyState);
     378           0 :     mReadyState = LOADING;
     379             :   }
     380             : 
     381           0 :   ++mPendingRequestCount;
     382           0 : }
     383             : 
     384             : void
     385           0 : IDBTransaction::OnRequestFinished(bool aActorDestroyedNormally)
     386             : {
     387           0 :   AssertIsOnOwningThread();
     388           0 :   MOZ_ASSERT(mPendingRequestCount);
     389             : 
     390           0 :   --mPendingRequestCount;
     391             : 
     392           0 :   if (!mPendingRequestCount) {
     393           0 :     mReadyState = COMMITTING;
     394             : 
     395           0 :     if (aActorDestroyedNormally) {
     396           0 :       if (NS_SUCCEEDED(mAbortCode)) {
     397           0 :         SendCommit();
     398             :       } else {
     399           0 :         SendAbort(mAbortCode);
     400             :       }
     401             :     } else {
     402             :       // Don't try to send any more messages to the parent if the request actor
     403             :       // was killed.
     404             : #ifdef DEBUG
     405           0 :       MOZ_ASSERT(!mSentCommitOrAbort);
     406           0 :       mSentCommitOrAbort = true;
     407             : #endif
     408           0 :       IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld]: "
     409             :                      "Request actor was killed, transaction will be aborted",
     410             :                    "IndexedDB %s: C T[%lld]: IDBTransaction abort",
     411             :                    IDB_LOG_ID_STRING(),
     412             :                    LoggingSerialNumber());
     413             :     }
     414             :   }
     415           0 : }
     416             : 
     417             : void
     418           0 : IDBTransaction::SendCommit()
     419             : {
     420           0 :   AssertIsOnOwningThread();
     421           0 :   MOZ_ASSERT(NS_SUCCEEDED(mAbortCode));
     422           0 :   MOZ_ASSERT(IsCommittingOrDone());
     423           0 :   MOZ_ASSERT(!mSentCommitOrAbort);
     424           0 :   MOZ_ASSERT(!mPendingRequestCount);
     425             : 
     426             :   // Don't do this in the macro because we always need to increment the serial
     427             :   // number to keep in sync with the parent.
     428           0 :   const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber();
     429             : 
     430           0 :   IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
     431             :                  "All requests complete, committing transaction",
     432             :                "IndexedDB %s: C T[%lld] R[%llu]: IDBTransaction commit",
     433             :                IDB_LOG_ID_STRING(),
     434             :                LoggingSerialNumber(),
     435             :                requestSerialNumber);
     436             : 
     437           0 :   if (mMode == VERSION_CHANGE) {
     438           0 :     MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
     439           0 :     mBackgroundActor.mVersionChangeBackgroundActor->SendCommit();
     440             :   } else {
     441           0 :     MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
     442           0 :     mBackgroundActor.mNormalBackgroundActor->SendCommit();
     443             :   }
     444             : 
     445             : #ifdef DEBUG
     446           0 :   mSentCommitOrAbort = true;
     447             : #endif
     448           0 : }
     449             : 
     450             : void
     451           0 : IDBTransaction::SendAbort(nsresult aResultCode)
     452             : {
     453           0 :   AssertIsOnOwningThread();
     454           0 :   MOZ_ASSERT(NS_FAILED(aResultCode));
     455           0 :   MOZ_ASSERT(IsCommittingOrDone());
     456           0 :   MOZ_ASSERT(!mSentCommitOrAbort);
     457             : 
     458             :   // Don't do this in the macro because we always need to increment the serial
     459             :   // number to keep in sync with the parent.
     460           0 :   const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber();
     461             : 
     462           0 :   IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
     463             :                  "Aborting transaction with result 0x%x",
     464             :                "IndexedDB %s: C T[%lld] R[%llu]: IDBTransaction abort (0x%x)",
     465             :                IDB_LOG_ID_STRING(),
     466             :                LoggingSerialNumber(),
     467             :                requestSerialNumber,
     468             :                aResultCode);
     469             : 
     470           0 :   if (mMode == VERSION_CHANGE) {
     471           0 :     MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
     472           0 :     mBackgroundActor.mVersionChangeBackgroundActor->SendAbort(aResultCode);
     473             :   } else {
     474           0 :     MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
     475           0 :     mBackgroundActor.mNormalBackgroundActor->SendAbort(aResultCode);
     476             :   }
     477             : 
     478             : #ifdef DEBUG
     479           0 :   mSentCommitOrAbort = true;
     480             : #endif
     481           0 : }
     482             : 
     483             : void
     484           0 : IDBTransaction::NoteActiveTransaction()
     485             : {
     486           0 :   AssertIsOnOwningThread();
     487           0 :   MOZ_ASSERT(!mNotedActiveTransaction);
     488             : 
     489           0 :   mDatabase->NoteActiveTransaction();
     490           0 :   mNotedActiveTransaction = true;
     491           0 : }
     492             : 
     493             : void
     494           0 : IDBTransaction::MaybeNoteInactiveTransaction()
     495             : {
     496           0 :   AssertIsOnOwningThread();
     497             : 
     498           0 :   if (mNotedActiveTransaction) {
     499           0 :     mDatabase->NoteInactiveTransaction();
     500           0 :     mNotedActiveTransaction = false;
     501             :   }
     502           0 : }
     503             : 
     504             : bool
     505           0 : IDBTransaction::IsOpen() const
     506             : {
     507           0 :   AssertIsOnOwningThread();
     508             : 
     509             :   // If we haven't started anything then we're open.
     510           0 :   if (mReadyState == IDBTransaction::INITIAL) {
     511           0 :     return true;
     512             :   }
     513             : 
     514             :   // If we've already started then we need to check to see if we still have the
     515             :   // mCreating flag set. If we do (i.e. we haven't returned to the event loop
     516             :   // from the time we were created) then we are open. Otherwise check the
     517             :   // currently running transaction to see if it's the same. We only allow other
     518             :   // requests to be made if this transaction is currently running.
     519           0 :   if (mReadyState == IDBTransaction::LOADING &&
     520           0 :       (mCreating || GetCurrent() == this)) {
     521           0 :     return true;
     522             :   }
     523             : 
     524           0 :   return false;
     525             : }
     526             : 
     527             : void
     528           0 : IDBTransaction::GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo,
     529             :                                   uint32_t* aColumn) const
     530             : {
     531           0 :   AssertIsOnOwningThread();
     532           0 :   MOZ_ASSERT(aLineNo);
     533           0 :   MOZ_ASSERT(aColumn);
     534             : 
     535           0 :   aFilename = mFilename;
     536           0 :   *aLineNo = mLineNo;
     537           0 :   *aColumn = mColumn;
     538           0 : }
     539             : 
     540             : already_AddRefed<IDBObjectStore>
     541           0 : IDBTransaction::CreateObjectStore(const ObjectStoreSpec& aSpec)
     542             : {
     543           0 :   AssertIsOnOwningThread();
     544           0 :   MOZ_ASSERT(aSpec.metadata().id());
     545           0 :   MOZ_ASSERT(VERSION_CHANGE == mMode);
     546           0 :   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
     547           0 :   MOZ_ASSERT(IsOpen());
     548             : 
     549             : #ifdef DEBUG
     550             :   {
     551           0 :     const nsString& name = aSpec.metadata().name();
     552             : 
     553           0 :     for (uint32_t count = mObjectStores.Length(), index = 0;
     554           0 :          index < count;
     555             :          index++) {
     556           0 :       MOZ_ASSERT(mObjectStores[index]->Name() != name);
     557             :     }
     558             :   }
     559             : #endif
     560             : 
     561           0 :   MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
     562             :                     SendCreateObjectStore(aSpec.metadata()));
     563             : 
     564           0 :   RefPtr<IDBObjectStore> objectStore = IDBObjectStore::Create(this, aSpec);
     565           0 :   MOZ_ASSERT(objectStore);
     566             : 
     567           0 :   mObjectStores.AppendElement(objectStore);
     568             : 
     569           0 :   return objectStore.forget();
     570             : }
     571             : 
     572             : void
     573           0 : IDBTransaction::DeleteObjectStore(int64_t aObjectStoreId)
     574             : {
     575           0 :   AssertIsOnOwningThread();
     576           0 :   MOZ_ASSERT(aObjectStoreId);
     577           0 :   MOZ_ASSERT(VERSION_CHANGE == mMode);
     578           0 :   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
     579           0 :   MOZ_ASSERT(IsOpen());
     580             : 
     581           0 :   MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
     582             :                     SendDeleteObjectStore(aObjectStoreId));
     583             : 
     584           0 :   for (uint32_t count = mObjectStores.Length(), index = 0;
     585           0 :        index < count;
     586             :        index++) {
     587           0 :     RefPtr<IDBObjectStore>& objectStore = mObjectStores[index];
     588             : 
     589           0 :     if (objectStore->Id() == aObjectStoreId) {
     590           0 :       objectStore->NoteDeletion();
     591             : 
     592             :       RefPtr<IDBObjectStore>* deletedObjectStore =
     593           0 :         mDeletedObjectStores.AppendElement();
     594           0 :       deletedObjectStore->swap(mObjectStores[index]);
     595             : 
     596           0 :       mObjectStores.RemoveElementAt(index);
     597           0 :       break;
     598             :     }
     599             :   }
     600           0 : }
     601             : 
     602             : void
     603           0 : IDBTransaction::RenameObjectStore(int64_t aObjectStoreId,
     604             :                                   const nsAString& aName)
     605             : {
     606           0 :   AssertIsOnOwningThread();
     607           0 :   MOZ_ASSERT(aObjectStoreId);
     608           0 :   MOZ_ASSERT(VERSION_CHANGE == mMode);
     609           0 :   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
     610           0 :   MOZ_ASSERT(IsOpen());
     611             : 
     612           0 :   MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
     613             :                     SendRenameObjectStore(aObjectStoreId, nsString(aName)));
     614           0 : }
     615             : 
     616             : void
     617           0 : IDBTransaction::CreateIndex(IDBObjectStore* aObjectStore,
     618             :                             const indexedDB::IndexMetadata& aMetadata)
     619             : {
     620           0 :   AssertIsOnOwningThread();
     621           0 :   MOZ_ASSERT(aObjectStore);
     622           0 :   MOZ_ASSERT(aMetadata.id());
     623           0 :   MOZ_ASSERT(VERSION_CHANGE == mMode);
     624           0 :   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
     625           0 :   MOZ_ASSERT(IsOpen());
     626             : 
     627           0 :   MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
     628             :                     SendCreateIndex(aObjectStore->Id(), aMetadata));
     629           0 : }
     630             : 
     631             : void
     632           0 : IDBTransaction::DeleteIndex(IDBObjectStore* aObjectStore,
     633             :                             int64_t aIndexId)
     634             : {
     635           0 :   AssertIsOnOwningThread();
     636           0 :   MOZ_ASSERT(aObjectStore);
     637           0 :   MOZ_ASSERT(aIndexId);
     638           0 :   MOZ_ASSERT(VERSION_CHANGE == mMode);
     639           0 :   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
     640           0 :   MOZ_ASSERT(IsOpen());
     641             : 
     642           0 :   MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
     643             :                     SendDeleteIndex(aObjectStore->Id(), aIndexId));
     644           0 : }
     645             : 
     646             : void
     647           0 : IDBTransaction::RenameIndex(IDBObjectStore* aObjectStore,
     648             :                             int64_t aIndexId,
     649             :                             const nsAString& aName)
     650             : {
     651           0 :   AssertIsOnOwningThread();
     652           0 :   MOZ_ASSERT(aObjectStore);
     653           0 :   MOZ_ASSERT(aIndexId);
     654           0 :   MOZ_ASSERT(VERSION_CHANGE == mMode);
     655           0 :   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
     656           0 :   MOZ_ASSERT(IsOpen());
     657             : 
     658           0 :   MOZ_ALWAYS_TRUE(mBackgroundActor.mVersionChangeBackgroundActor->
     659             :                     SendRenameIndex(aObjectStore->Id(),
     660             :                                     aIndexId,
     661             :                                     nsString(aName)));
     662           0 : }
     663             : 
     664             : void
     665           0 : IDBTransaction::AbortInternal(nsresult aAbortCode,
     666             :                               already_AddRefed<DOMError> aError)
     667             : {
     668           0 :   AssertIsOnOwningThread();
     669           0 :   MOZ_ASSERT(NS_FAILED(aAbortCode));
     670           0 :   MOZ_ASSERT(!IsCommittingOrDone());
     671             : 
     672           0 :   RefPtr<DOMError> error = aError;
     673             : 
     674           0 :   const bool isVersionChange = mMode == VERSION_CHANGE;
     675           0 :   const bool isInvalidated = mDatabase->IsInvalidated();
     676           0 :   bool needToSendAbort = mReadyState == INITIAL;
     677             : 
     678           0 :   mAbortCode = aAbortCode;
     679           0 :   mReadyState = DONE;
     680           0 :   mError = error.forget();
     681             : 
     682           0 :   if (isVersionChange) {
     683             :     // If a version change transaction is aborted, we must revert the world
     684             :     // back to its previous state unless we're being invalidated after the
     685             :     // transaction already completed.
     686           0 :     if (!isInvalidated) {
     687           0 :       mDatabase->RevertToPreviousState();
     688             :     }
     689             : 
     690             :     // We do the reversion only for the mObjectStores/mDeletedObjectStores but
     691             :     // not for the mIndexes/mDeletedIndexes of each IDBObjectStore because it's
     692             :     // time-consuming(O(m*n)) and mIndexes/mDeletedIndexes won't be used anymore
     693             :     // in IDBObjectStore::(Create|Delete)Index() and IDBObjectStore::Index() in
     694             :     // which all the executions are returned earlier by !transaction->IsOpen().
     695             : 
     696             :     const nsTArray<ObjectStoreSpec>& specArray =
     697           0 :       mDatabase->Spec()->objectStores();
     698             : 
     699           0 :     if (specArray.IsEmpty()) {
     700           0 :       mObjectStores.Clear();
     701           0 :       mDeletedObjectStores.Clear();
     702             :     } else {
     703           0 :       nsTHashtable<nsUint64HashKey> validIds(specArray.Length());
     704             : 
     705           0 :       for (uint32_t specCount = specArray.Length(), specIndex = 0;
     706           0 :            specIndex < specCount;
     707             :            specIndex++) {
     708           0 :         const int64_t objectStoreId = specArray[specIndex].metadata().id();
     709           0 :         MOZ_ASSERT(objectStoreId);
     710             : 
     711           0 :         validIds.PutEntry(uint64_t(objectStoreId));
     712             :       }
     713             : 
     714           0 :       for (uint32_t objCount = mObjectStores.Length(), objIndex = 0;
     715           0 :             objIndex < objCount;
     716             :             /* incremented conditionally */) {
     717           0 :         const int64_t objectStoreId = mObjectStores[objIndex]->Id();
     718           0 :         MOZ_ASSERT(objectStoreId);
     719             : 
     720           0 :         if (validIds.Contains(uint64_t(objectStoreId))) {
     721           0 :           objIndex++;
     722             :         } else {
     723           0 :           mObjectStores.RemoveElementAt(objIndex);
     724           0 :           objCount--;
     725             :         }
     726             :       }
     727             : 
     728           0 :       if (!mDeletedObjectStores.IsEmpty()) {
     729           0 :         for (uint32_t objCount = mDeletedObjectStores.Length(), objIndex = 0;
     730           0 :               objIndex < objCount;
     731             :               objIndex++) {
     732           0 :           const int64_t objectStoreId = mDeletedObjectStores[objIndex]->Id();
     733           0 :           MOZ_ASSERT(objectStoreId);
     734             : 
     735           0 :           if (validIds.Contains(uint64_t(objectStoreId))) {
     736             :             RefPtr<IDBObjectStore>* objectStore =
     737           0 :               mObjectStores.AppendElement();
     738           0 :             objectStore->swap(mDeletedObjectStores[objIndex]);
     739             :           }
     740             :         }
     741           0 :         mDeletedObjectStores.Clear();
     742             :       }
     743             :     }
     744             :   }
     745             : 
     746             :   // Fire the abort event if there are no outstanding requests. Otherwise the
     747             :   // abort event will be fired when all outstanding requests finish.
     748           0 :   if (needToSendAbort) {
     749           0 :     SendAbort(aAbortCode);
     750             :   }
     751             : 
     752           0 :   if (isVersionChange) {
     753           0 :     mDatabase->Close();
     754             :   }
     755           0 : }
     756             : 
     757             : void
     758           0 : IDBTransaction::Abort(IDBRequest* aRequest)
     759             : {
     760           0 :   AssertIsOnOwningThread();
     761           0 :   MOZ_ASSERT(aRequest);
     762             : 
     763           0 :   if (IsCommittingOrDone()) {
     764             :     // Already started (and maybe finished) the commit or abort so there is
     765             :     // nothing to do here.
     766           0 :     return;
     767             :   }
     768             : 
     769           0 :   ErrorResult rv;
     770           0 :   RefPtr<DOMError> error = aRequest->GetError(rv);
     771             : 
     772           0 :   AbortInternal(aRequest->GetErrorCode(), error.forget());
     773             : }
     774             : 
     775             : void
     776           0 : IDBTransaction::Abort(nsresult aErrorCode)
     777             : {
     778           0 :   AssertIsOnOwningThread();
     779             : 
     780           0 :   if (IsCommittingOrDone()) {
     781             :     // Already started (and maybe finished) the commit or abort so there is
     782             :     // nothing to do here.
     783           0 :     return;
     784             :   }
     785             : 
     786           0 :   RefPtr<DOMError> error = new DOMError(GetOwner(), aErrorCode);
     787           0 :   AbortInternal(aErrorCode, error.forget());
     788             : }
     789             : 
     790             : void
     791           0 : IDBTransaction::Abort(ErrorResult& aRv)
     792             : {
     793           0 :   AssertIsOnOwningThread();
     794             : 
     795           0 :   if (IsCommittingOrDone()) {
     796           0 :     aRv = NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
     797           0 :     return;
     798             :   }
     799             : 
     800           0 :   AbortInternal(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR, nullptr);
     801             : 
     802           0 :   MOZ_ASSERT(!mAbortedByScript);
     803           0 :   mAbortedByScript = true;
     804             : }
     805             : 
     806             : void
     807           0 : IDBTransaction::FireCompleteOrAbortEvents(nsresult aResult)
     808             : {
     809           0 :   AssertIsOnOwningThread();
     810           0 :   MOZ_ASSERT(!mFiredCompleteOrAbort);
     811             : 
     812           0 :   mReadyState = DONE;
     813             : 
     814             : #ifdef DEBUG
     815           0 :   mFiredCompleteOrAbort = true;
     816             : #endif
     817             : 
     818             :   // Make sure we drop the WorkerHolder when this function completes.
     819           0 :   nsAutoPtr<WorkerHolder> workerHolder = Move(mWorkerHolder);
     820             : 
     821           0 :   nsCOMPtr<nsIDOMEvent> event;
     822           0 :   if (NS_SUCCEEDED(aResult)) {
     823           0 :     event = CreateGenericEvent(this,
     824           0 :                                nsDependentString(kCompleteEventType),
     825             :                                eDoesNotBubble,
     826           0 :                                eNotCancelable);
     827           0 :     MOZ_ASSERT(event);
     828             :   } else {
     829           0 :     if (aResult == NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR) {
     830           0 :       mDatabase->SetQuotaExceeded();
     831             :     }
     832             : 
     833           0 :     if (!mError && !mAbortedByScript) {
     834           0 :       mError = new DOMError(GetOwner(), aResult);
     835             :     }
     836             : 
     837           0 :     event = CreateGenericEvent(this,
     838           0 :                                nsDependentString(kAbortEventType),
     839             :                                eDoesBubble,
     840           0 :                                eNotCancelable);
     841           0 :     MOZ_ASSERT(event);
     842             :   }
     843             : 
     844           0 :   if (NS_SUCCEEDED(mAbortCode)) {
     845           0 :     IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld]: "
     846             :                    "Firing 'complete' event",
     847             :                  "IndexedDB %s: C T[%lld]: IDBTransaction 'complete' event",
     848             :                  IDB_LOG_ID_STRING(),
     849             :                  mLoggingSerialNumber);
     850             :   } else {
     851           0 :     IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld]: "
     852             :                    "Firing 'abort' event with error 0x%x",
     853             :                  "IndexedDB %s: C T[%lld]: IDBTransaction 'abort' event (0x%x)",
     854             :                  IDB_LOG_ID_STRING(),
     855             :                  mLoggingSerialNumber,
     856             :                  mAbortCode);
     857             :   }
     858             : 
     859             :   bool dummy;
     860           0 :   if (NS_FAILED(DispatchEvent(event, &dummy))) {
     861           0 :     NS_WARNING("DispatchEvent failed!");
     862             :   }
     863             : 
     864             :   // Normally, we note inactive transaction here instead of
     865             :   // IDBTransaction::ClearBackgroundActor() because here is the earliest place
     866             :   // to know that it becomes non-blocking to allow the scheduler to start the
     867             :   // preemption as soon as it can.
     868             :   // Note: If the IDBTransaction object is held by the script,
     869             :   // ClearBackgroundActor() will be done in ~IDBTransaction() until garbage
     870             :   // collected after its window is closed which prevents us to preempt its
     871             :   // window immediately after committed.
     872           0 :   MaybeNoteInactiveTransaction();
     873           0 : }
     874             : 
     875             : int64_t
     876           0 : IDBTransaction::NextObjectStoreId()
     877             : {
     878           0 :   AssertIsOnOwningThread();
     879           0 :   MOZ_ASSERT(VERSION_CHANGE == mMode);
     880             : 
     881           0 :   return mNextObjectStoreId++;
     882             : }
     883             : 
     884             : int64_t
     885           0 : IDBTransaction::NextIndexId()
     886             : {
     887           0 :   AssertIsOnOwningThread();
     888           0 :   MOZ_ASSERT(VERSION_CHANGE == mMode);
     889             : 
     890           0 :   return mNextIndexId++;
     891             : }
     892             : 
     893             : nsPIDOMWindowInner*
     894           0 : IDBTransaction::GetParentObject() const
     895             : {
     896           0 :   AssertIsOnOwningThread();
     897             : 
     898           0 :   return mDatabase->GetParentObject();
     899             : }
     900             : 
     901             : IDBTransactionMode
     902           0 : IDBTransaction::GetMode(ErrorResult& aRv) const
     903             : {
     904           0 :   AssertIsOnOwningThread();
     905             : 
     906           0 :   switch (mMode) {
     907             :     case READ_ONLY:
     908           0 :       return IDBTransactionMode::Readonly;
     909             : 
     910             :     case READ_WRITE:
     911           0 :       return IDBTransactionMode::Readwrite;
     912             : 
     913             :     case READ_WRITE_FLUSH:
     914           0 :       return IDBTransactionMode::Readwriteflush;
     915             : 
     916             :     case CLEANUP:
     917           0 :       return IDBTransactionMode::Cleanup;
     918             : 
     919             :     case VERSION_CHANGE:
     920           0 :       return IDBTransactionMode::Versionchange;
     921             : 
     922             :     case MODE_INVALID:
     923             :     default:
     924           0 :       MOZ_CRASH("Bad mode!");
     925             :   }
     926             : }
     927             : 
     928             : DOMError*
     929           0 : IDBTransaction::GetError() const
     930             : {
     931           0 :   AssertIsOnOwningThread();
     932             : 
     933           0 :   return mError;
     934             : }
     935             : 
     936             : already_AddRefed<DOMStringList>
     937           0 : IDBTransaction::ObjectStoreNames() const
     938             : {
     939           0 :   AssertIsOnOwningThread();
     940             : 
     941           0 :   if (mMode == IDBTransaction::VERSION_CHANGE) {
     942           0 :     return mDatabase->ObjectStoreNames();
     943             :   }
     944             : 
     945           0 :   RefPtr<DOMStringList> list = new DOMStringList();
     946           0 :   list->StringArray() = mObjectStoreNames;
     947           0 :   return list.forget();
     948             : }
     949             : 
     950             : already_AddRefed<IDBObjectStore>
     951           0 : IDBTransaction::ObjectStore(const nsAString& aName, ErrorResult& aRv)
     952             : {
     953           0 :   AssertIsOnOwningThread();
     954             : 
     955           0 :   if (IsCommittingOrDone()) {
     956           0 :     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     957           0 :     return nullptr;
     958             :   }
     959             : 
     960           0 :   const ObjectStoreSpec* spec = nullptr;
     961             : 
     962           0 :   if (IDBTransaction::VERSION_CHANGE == mMode ||
     963           0 :       mObjectStoreNames.Contains(aName)) {
     964             :     const nsTArray<ObjectStoreSpec>& objectStores =
     965           0 :       mDatabase->Spec()->objectStores();
     966             : 
     967           0 :     for (uint32_t count = objectStores.Length(), index = 0;
     968           0 :          index < count;
     969             :          index++) {
     970           0 :       const ObjectStoreSpec& objectStore = objectStores[index];
     971           0 :       if (objectStore.metadata().name() == aName) {
     972           0 :         spec = &objectStore;
     973           0 :         break;
     974             :       }
     975             :     }
     976             :   }
     977             : 
     978           0 :   if (!spec) {
     979           0 :     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR);
     980           0 :     return nullptr;
     981             :   }
     982             : 
     983           0 :   const int64_t desiredId = spec->metadata().id();
     984             : 
     985           0 :   RefPtr<IDBObjectStore> objectStore;
     986             : 
     987           0 :   for (uint32_t count = mObjectStores.Length(), index = 0;
     988           0 :        index < count;
     989             :        index++) {
     990           0 :     RefPtr<IDBObjectStore>& existingObjectStore = mObjectStores[index];
     991             : 
     992           0 :     if (existingObjectStore->Id() == desiredId) {
     993           0 :       objectStore = existingObjectStore;
     994           0 :       break;
     995             :     }
     996             :   }
     997             : 
     998           0 :   if (!objectStore) {
     999           0 :     objectStore = IDBObjectStore::Create(this, *spec);
    1000           0 :     MOZ_ASSERT(objectStore);
    1001             : 
    1002           0 :     mObjectStores.AppendElement(objectStore);
    1003             :   }
    1004             : 
    1005           0 :   return objectStore.forget();
    1006             : }
    1007             : 
    1008           0 : NS_IMPL_ADDREF_INHERITED(IDBTransaction, IDBWrapperCache)
    1009           0 : NS_IMPL_RELEASE_INHERITED(IDBTransaction, IDBWrapperCache)
    1010             : 
    1011           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBTransaction)
    1012           0 :   NS_INTERFACE_MAP_ENTRY(nsIRunnable)
    1013           0 : NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
    1014             : 
    1015             : NS_IMPL_CYCLE_COLLECTION_CLASS(IDBTransaction)
    1016             : 
    1017           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBTransaction,
    1018             :                                                   IDBWrapperCache)
    1019           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDatabase)
    1020           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
    1021           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObjectStores)
    1022           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeletedObjectStores)
    1023           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    1024             : 
    1025           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction, IDBWrapperCache)
    1026             :   // Don't unlink mDatabase!
    1027           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
    1028           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mObjectStores)
    1029           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDeletedObjectStores)
    1030           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    1031             : 
    1032             : JSObject*
    1033           0 : IDBTransaction::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
    1034             : {
    1035           0 :   AssertIsOnOwningThread();
    1036             : 
    1037           0 :   return IDBTransactionBinding::Wrap(aCx, this, aGivenProto);
    1038             : }
    1039             : 
    1040             : nsresult
    1041           0 : IDBTransaction::GetEventTargetParent(EventChainPreVisitor& aVisitor)
    1042             : {
    1043           0 :   AssertIsOnOwningThread();
    1044             : 
    1045           0 :   aVisitor.mCanHandle = true;
    1046           0 :   aVisitor.mParentTarget = mDatabase;
    1047           0 :   return NS_OK;
    1048             : }
    1049             : 
    1050             : NS_IMETHODIMP
    1051           0 : IDBTransaction::Run()
    1052             : {
    1053           0 :   AssertIsOnOwningThread();
    1054             : 
    1055             :   // We're back at the event loop, no longer newborn.
    1056           0 :   mCreating = false;
    1057             : 
    1058             :   // Maybe commit if there were no requests generated.
    1059           0 :   if (mReadyState == IDBTransaction::INITIAL) {
    1060           0 :     mReadyState = DONE;
    1061             : 
    1062           0 :     SendCommit();
    1063             :   }
    1064             : 
    1065           0 :   return NS_OK;
    1066             : }
    1067             : 
    1068             : bool
    1069           0 : IDBTransaction::
    1070             : WorkerHolder::Notify(Status aStatus)
    1071             : {
    1072           0 :   MOZ_ASSERT(mWorkerPrivate);
    1073           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
    1074           0 :   MOZ_ASSERT(aStatus > Running);
    1075             : 
    1076           0 :   if (mTransaction && aStatus > Terminating) {
    1077           0 :     mTransaction->AssertIsOnOwningThread();
    1078             : 
    1079           0 :     RefPtr<IDBTransaction> transaction = Move(mTransaction);
    1080             : 
    1081           0 :     if (!transaction->IsCommittingOrDone()) {
    1082           0 :       IDB_REPORT_INTERNAL_ERR();
    1083           0 :       transaction->AbortInternal(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR, nullptr);
    1084             :     }
    1085             :   }
    1086             : 
    1087           0 :   return true;
    1088             : }
    1089             : 
    1090             : } // namespace dom
    1091             : } // namespace mozilla

Generated by: LCOV version 1.13