Bug 1155634 - Move ConnectionPool creation closer to where we actually use it and at a point guaranteed to be after QuotaManager has been started. r=khuey, a=jocheng
authorBen Turner <bent.mozilla@gmail.com>
Mon, 04 May 2015 15:58:00 -0400
changeset 238354 28b7fe8921516a355cbca82dbcd0691e5e8581cc
parent 238353 d38edfcbbf8e8a7ba60ce391a4ba50b85e4f92ec
child 238355 ae7e61e290cbc76b4cc966a95a3dae27bd54e964
push id586
push userryanvm@gmail.com
push dateMon, 11 May 2015 21:56:27 +0000
treeherdermozilla-b2g37_v2_2@70782f19acbf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey, jocheng
bugs1155634
milestone37.0
Bug 1155634 - Move ConnectionPool creation closer to where we actually use it and at a point guaranteed to be after QuotaManager has been started. r=khuey, a=jocheng
dom/indexedDB/ActorsParent.cpp
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -3158,17 +3158,17 @@ protected:
 private:
   nsRefPtr<Database> mDatabase;
   nsCOMPtr<mozIStorageConnection> mConnection;
   nsRefPtr<UpdateRefcountFunction> mUpdateFileRefcountFunction;
   nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
     mCachedStatements;
   nsTArray<nsRefPtr<FullObjectStoreMetadata>>
     mModifiedAutoIncrementObjectStoreMetadataArray;
-  const uint64_t mTransactionId;
+  uint64_t mTransactionId;
   const nsCString mDatabaseId;
   const int64_t mLoggingSerialNumber;
   uint64_t mActiveRequestCount;
   Atomic<bool> mInvalidatedOnAnyThread;
   Mode mMode;
   bool mHasBeenActive;
   bool mActorDestroyed;
   bool mInvalidated;
@@ -3212,20 +3212,22 @@ public:
   // May be called on any thread, but is more expensive than IsInvalidated().
   bool
   IsInvalidatedOnAnyThread() const
   {
     return mInvalidatedOnAnyThread;
   }
 
   void
-  SetActive()
+  SetActive(uint64_t aTransactionId)
   {
     AssertIsOnBackgroundThread();
-
+    MOZ_ASSERT(aTransactionId);
+
+    mTransactionId = aTransactionId;
     mHasBeenActive = true;
   }
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(
     mozilla::dom::indexedDB::TransactionBase)
 
   nsresult
   GetCachedStatement(const nsACString& aQuery,
@@ -5876,26 +5878,16 @@ Factory::~Factory()
 already_AddRefed<Factory>
 Factory::Create(const LoggingInfo& aLoggingInfo)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread());
 
   // If this is the first instance then we need to do some initialization.
   if (!sFactoryInstanceCount) {
-    if (!gTransactionThreadPool) {
-      nsRefPtr<TransactionThreadPool> threadPool =
-        TransactionThreadPool::Create();
-      if (NS_WARN_IF(!threadPool)) {
-        return nullptr;
-      }
-
-      gTransactionThreadPool = threadPool;
-    }
-
     MOZ_ASSERT(!gLiveDatabaseHashtable);
     gLiveDatabaseHashtable = new DatabaseActorHashtable();
 
     MOZ_ASSERT(!gStartTransactionRunnable);
     gStartTransactionRunnable = new nsRunnable();
 
     MOZ_ASSERT(!gLoggingInfoHashtable);
     gLoggingInfoHashtable = new DatabaseLoggingInfoHashtable();
@@ -6538,29 +6530,40 @@ Database::RecvPBackgroundIDBTransactionC
   MOZ_ASSERT(!mClosed);
 
   if (IsInvalidated()) {
     // This is an expected race. We don't want the child to die here, just don't
     // actually do any work.
     return true;
   }
 
+  if (!gTransactionThreadPool) {
+    nsRefPtr<TransactionThreadPool> threadPool =
+      TransactionThreadPool::Create();
+    if (NS_WARN_IF(!threadPool)) {
+      return nullptr;
+    }
+
+    gTransactionThreadPool = threadPool;
+  }
+
+  const uint64_t transactionId = gTransactionThreadPool->NextTransactionId();
+
   auto* transaction = static_cast<NormalTransaction*>(aActor);
+  transaction->SetActive(transactionId);
 
   // Add a placeholder for this transaction immediately.
-  gTransactionThreadPool->Start(transaction->TransactionId(),
+  gTransactionThreadPool->Start(transactionId,
                                 mMetadata->mDatabaseId,
                                 aObjectStoreNames,
                                 aMode,
                                 GetLoggingInfo()->Id(),
                                 transaction->LoggingSerialNumber(),
                                 gStartTransactionRunnable);
 
-  transaction->SetActive();
-
   if (NS_WARN_IF(!RegisterTransaction(transaction))) {
     IDB_REPORT_INTERNAL_ERR();
     transaction->Abort(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR, /* aForce */ false);
     return true;
   }
 
   return true;
 }
@@ -6643,17 +6646,17 @@ Database::RecvClose()
 }
 
 /*******************************************************************************
  * TransactionBase
  ******************************************************************************/
 
 TransactionBase::TransactionBase(Database* aDatabase, Mode aMode)
   : mDatabase(aDatabase)
-  , mTransactionId(gTransactionThreadPool->NextTransactionId())
+  , mTransactionId(0)
   , mDatabaseId(aDatabase->Id())
   , mLoggingSerialNumber(aDatabase->GetLoggingInfo()->NextTransactionSN(aMode))
   , mActiveRequestCount(0)
   , mInvalidatedOnAnyThread(false)
   , mMode(aMode)
   , mHasBeenActive(false)
   , mActorDestroyed(false)
   , mInvalidated(false)
@@ -6661,17 +6664,16 @@ TransactionBase::TransactionBase(Databas
   , mCommitOrAbortReceived(false)
   , mCommittedOrAborted(false)
   , mForceAborted(false)
   , mTransactionThread(nullptr)
   , mSavepointCount(0)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aDatabase);
-  MOZ_ASSERT(mTransactionId);
   MOZ_ASSERT(mLoggingSerialNumber);
 }
 
 TransactionBase::~TransactionBase()
 {
   MOZ_ASSERT(!mSavepointCount);
   MOZ_ASSERT(!mActiveRequestCount);
   MOZ_ASSERT(mActorDestroyed);
@@ -10676,25 +10678,28 @@ FactoryOp::WaitForTransactions()
   MOZ_ASSERT(mState == State_BeginVersionChange ||
              mState == State_WaitingForOtherDatabasesToClose);
   MOZ_ASSERT(!mDatabaseId.IsEmpty());
   MOZ_ASSERT(!IsActorDestroyed());
 
   nsTArray<nsCString> databaseIds;
   databaseIds.AppendElement(mDatabaseId);
 
+  mState = State_WaitingForTransactionsToComplete;
+
   nsRefPtr<TransactionThreadPool> threadPool = gTransactionThreadPool.get();
-  MOZ_ASSERT(threadPool);
-
-  // WaitForDatabasesToComplete() will run this op immediately if there are no
-  // transactions blocking it, so be sure to set the next state here before
-  // calling it.
-  mState = State_WaitingForTransactionsToComplete;
-
-  threadPool->WaitForDatabasesToComplete(databaseIds, this);
+  if (threadPool) {
+    // WaitForDatabasesToComplete() will run this op immediately if there are no
+    // transactions blocking it, so be sure to set the next state here before
+    // calling it.
+
+    threadPool->WaitForDatabasesToComplete(databaseIds, this);
+  } else {
+    unused << Run();
+  }
   return;
 }
 
 void
 FactoryOp::FinishSendResults()
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mState == State_SendingResults);
@@ -11839,38 +11844,51 @@ OpenDatabaseOp::DispatchToWorkThread()
   MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty());
 
   if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) ||
       IsActorDestroyed()) {
     IDB_REPORT_INTERNAL_ERR();
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
+  if (!gTransactionThreadPool) {
+    nsRefPtr<TransactionThreadPool> threadPool =
+      TransactionThreadPool::Create();
+    if (!threadPool) {
+      IDB_REPORT_INTERNAL_ERR();
+      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+    }
+
+    gTransactionThreadPool = threadPool;
+  }
+
+  const uint64_t transactionId = gTransactionThreadPool->NextTransactionId();
+
   mState = State_DatabaseWorkVersionChange;
 
   // Intentionally empty.
   nsTArray<nsString> objectStoreNames;
 
   const int64_t loggingSerialNumber =
     mVersionChangeTransaction->LoggingSerialNumber();
   const nsID& backgroundChildLoggingId =
     mVersionChangeTransaction->GetLoggingInfo()->Id();
 
   nsRefPtr<VersionChangeOp> versionChangeOp = new VersionChangeOp(this);
 
-  gTransactionThreadPool->Start(mVersionChangeTransaction->TransactionId(),
+  mVersionChangeTransaction->SetActive(transactionId);
+
+  gTransactionThreadPool->Start(transactionId,
                                 mVersionChangeTransaction->DatabaseId(),
                                 objectStoreNames,
                                 mVersionChangeTransaction->GetMode(),
                                 backgroundChildLoggingId,
                                 loggingSerialNumber,
                                 versionChangeOp);
 
-  mVersionChangeTransaction->SetActive();
-
   mVersionChangeTransaction->NoteActiveRequest();
 
   if (NS_WARN_IF(!mDatabase->RegisterTransaction(mVersionChangeTransaction))) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }