Bug 1598164 - Made some boolean flags in IDBTransaction FlippedOnce to reduce statefulness. r=dom-workers-and-storage-reviewers,ytausky draft
authorSimon Giesecke <sgiesecke@mozilla.com>
Wed, 04 Dec 2019 12:51:25 +0000
changeset 2514410 bd7c43432670facdd2a78244d6de5a871c33aa5d
parent 2514409 7d32f16c841f565534cd2163fba40a319ae679b2
child 2514411 d6f6e0e4ea117fa27274e6539112cc7fce23fcc8
push id459908
push userreviewbot
push dateWed, 04 Dec 2019 12:51:53 +0000
treeherdertry@dbe3fcb3ec01 [default view] [failures only]
reviewersdom-workers-and-storage-reviewers, ytausky
bugs1598164
milestone72.0a1
Bug 1598164 - Made some boolean flags in IDBTransaction FlippedOnce to reduce statefulness. r=dom-workers-and-storage-reviewers,ytausky Differential Revision: https://phabricator.services.mozilla.com/D55081 Differential Diff: PHID-DIFF-vt6yqbmlrrk5ukf4hras
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/IDBTransaction.h
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -102,24 +102,17 @@ IDBTransaction::IDBTransaction(IDBDataba
       mAbortCode(NS_OK),
       mPendingRequestCount(0),
       mFilename(std::move(aFilename)),
       mLineNo(aLineNo),
       mColumn(aColumn),
       mMode(aMode),
       mCreating(false),
       mRegistered(false),
-      mAbortedByScript(false),
-      mNotedActiveTransaction(false)
-#ifdef DEBUG
-      ,
-      mSentCommitOrAbort(false),
-      mFiredCompleteOrAbort(false)
-#endif
-{
+      mNotedActiveTransaction(false) {
   MOZ_ASSERT(aDatabase);
   aDatabase->AssertIsOnOwningThread();
 
   // This also nulls mBackgroundActor.mVersionChangeBackgroundActor, so this is
   // valid also for mMode == Mode::VersionChange.
   mBackgroundActor.mNormalBackgroundActor = nullptr;
 
 #ifdef DEBUG
@@ -232,18 +225,17 @@ RefPtr<IDBTransaction> IDBTransaction::C
             IDB_REPORT_INTERNAL_ERR();
             transaction->AbortInternal(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR,
                                        nullptr);
           }
         });
     if (NS_WARN_IF(!workerRef)) {
       // Silence the destructor assertion if we never made this object live.
 #ifdef DEBUG
-      MOZ_ASSERT(!transaction->mSentCommitOrAbort);
-      transaction->mSentCommitOrAbort = true;
+      transaction->mSentCommitOrAbort.Flip();
 #endif
       return nullptr;
     }
 
     transaction->mWorkerRef = std::move(workerRef);
   }
 
   nsCOMPtr<nsIRunnable> runnable = do_QueryObject(transaction);
@@ -337,18 +329,17 @@ void IDBTransaction::RefreshSpec(const b
   }
 }
 
 void IDBTransaction::OnNewRequest() {
   AssertIsOnOwningThread();
 
   if (!mPendingRequestCount) {
     MOZ_ASSERT(ReadyState::Active == mReadyState);
-    MOZ_ASSERT(!mStarted);
-    mStarted = true;
+    mStarted.Flip();
   }
 
   ++mPendingRequestCount;
 }
 
 void IDBTransaction::OnRequestFinished(
     const bool aRequestCompletedSuccessfully) {
   AssertIsOnOwningThread();
@@ -369,67 +360,64 @@ void IDBTransaction::OnRequestFinished(
         SendCommit();
       } else {
         SendAbort(mAbortCode);
       }
     } else {
       // Don't try to send any more messages to the parent if the request actor
       // was killed.
 #ifdef DEBUG
-      MOZ_ASSERT(!mSentCommitOrAbort);
-      mSentCommitOrAbort = true;
+      mSentCommitOrAbort.Flip();
 #endif
       IDB_LOG_MARK_CHILD_TRANSACTION(
           "Request actor was killed, transaction will be aborted",
           "IDBTransaction abort", LoggingSerialNumber());
     }
   }
 }
 
 void IDBTransaction::SendCommit() {
   AssertIsOnOwningThread();
   MOZ_ASSERT(NS_SUCCEEDED(mAbortCode));
   MOZ_ASSERT(IsCommittingOrFinished());
-  MOZ_ASSERT(!mSentCommitOrAbort);
   MOZ_ASSERT(!mPendingRequestCount);
 
   // Don't do this in the macro because we always need to increment the serial
   // number to keep in sync with the parent.
   const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber();
 
   IDB_LOG_MARK_CHILD_TRANSACTION_REQUEST(
       "All requests complete, committing transaction", "IDBTransaction commit",
       LoggingSerialNumber(), requestSerialNumber);
 
   DoWithTransactionChild([](auto& actor) { actor.SendCommit(); });
 
 #ifdef DEBUG
-  mSentCommitOrAbort = true;
+  mSentCommitOrAbort.Flip();
 #endif
 }
 
 void IDBTransaction::SendAbort(const nsresult aResultCode) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(NS_FAILED(aResultCode));
   MOZ_ASSERT(IsCommittingOrFinished());
-  MOZ_ASSERT(!mSentCommitOrAbort);
 
   // Don't do this in the macro because we always need to increment the serial
   // number to keep in sync with the parent.
   const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber();
 
   IDB_LOG_MARK_CHILD_TRANSACTION_REQUEST(
       "Aborting transaction with result 0x%x", "IDBTransaction abort (0x%x)",
       LoggingSerialNumber(), requestSerialNumber, aResultCode);
 
   DoWithTransactionChild(
       [aResultCode](auto& actor) { actor.SendAbort(aResultCode); });
 
 #ifdef DEBUG
-  mSentCommitOrAbort = true;
+  mSentCommitOrAbort.Flip();
 #endif
 }
 
 void IDBTransaction::NoteActiveTransaction() {
   AssertIsOnOwningThread();
   MOZ_ASSERT(!mNotedActiveTransaction);
 
   mDatabase->NoteActiveTransaction();
@@ -699,28 +687,27 @@ void IDBTransaction::Abort(ErrorResult& 
 
   if (IsCommittingOrFinished()) {
     aRv = NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
     return;
   }
 
   AbortInternal(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR, nullptr);
 
-  MOZ_ASSERT(!mAbortedByScript);
-  mAbortedByScript = true;
+  mAbortedByScript.Flip();
 }
 
 void IDBTransaction::FireCompleteOrAbortEvents(const nsresult aResult) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(!mFiredCompleteOrAbort);
 
   mReadyState = ReadyState::Finished;
 
 #ifdef DEBUG
-  mFiredCompleteOrAbort = true;
+  mFiredCompleteOrAbort.Flip();
 #endif
 
   // Make sure we drop the WorkerRef when this function completes.
   const auto scopeExit = MakeScopeExit([&] { mWorkerRef = nullptr; });
 
   RefPtr<Event> event;
   if (NS_SUCCEEDED(aResult)) {
     event = CreateGenericEvent(this, nsDependentString(kCompleteEventType),
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_idbtransaction_h__
 #define mozilla_dom_idbtransaction_h__
 
+#include "FlippedOnce.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/IDBTransactionBinding.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIRunnable.h"
 #include "nsString.h"
 #include "nsTArray.h"
@@ -97,30 +98,30 @@ class IDBTransaction final : public DOME
                                   ///< transaction can auto-commit when the last
                                   ///< pending request finished.
 
   const nsString mFilename;
   const uint32_t mLineNo;
   const uint32_t mColumn;
 
   ReadyState mReadyState = ReadyState::Active;
-  bool mStarted = false;
+  FlippedOnce<false> mStarted;
   const Mode mMode;
 
   bool mCreating;    ///< Set between successful creation until the transaction
                      ///< has run on the event-loop.
   bool mRegistered;  ///< Whether mDatabase->RegisterTransaction() has been
                      ///< called (which may not be the case if construction was
                      ///< incomplete).
-  bool mAbortedByScript;
+  FlippedOnce<false> mAbortedByScript;
   bool mNotedActiveTransaction;
 
 #ifdef DEBUG
-  bool mSentCommitOrAbort;
-  bool mFiredCompleteOrAbort;
+  FlippedOnce<false> mSentCommitOrAbort;
+  FlippedOnce<false> mFiredCompleteOrAbort;
 #endif
 
  public:
   static MOZ_MUST_USE RefPtr<IDBTransaction> CreateVersionChange(
       IDBDatabase* aDatabase,
       indexedDB::BackgroundVersionChangeTransactionChild* aActor,
       IDBOpenDBRequest* aOpenRequest, int64_t aNextObjectStoreId,
       int64_t aNextIndexId);