From 2922453b6ea78748b436fa030ea7a6ba28a2dd1d Mon Sep 17 00:00:00 2001 From: Mihai Alexandru Michis Date: Thu, 19 Mar 2020 13:30:26 +0200 Subject: [PATCH] Backed out 10 changesets (bug 1623278, bug 1617170, bug 1620273, bug 1597954) for causing bustages. CLOSED TREE Backed out changeset 50c0e58dd654 (bug 1623278) Backed out changeset b31ddbcdd2f2 (bug 1597954) Backed out changeset 8b03993a9234 (bug 1623278) Backed out changeset ad7b08acadd6 (bug 1623278) Backed out changeset bb094a6084b3 (bug 1623278) Backed out changeset 7fdf38a403bb (bug 1623278) Backed out changeset d69cf5fcb571 (bug 1620273) Backed out changeset 5abef9862e60 (bug 1617170) Backed out changeset 11d9ccb4ddd8 (bug 1617170) Backed out changeset 6df7028b41d0 (bug 1617170) --- dom/indexedDB/ActorsChild.cpp | 39 +- dom/indexedDB/ActorsChild.h | 5 +- dom/indexedDB/ActorsParent.cpp | 1173 ++++++++--------- dom/indexedDB/FileInfoT.h | 7 +- dom/indexedDB/FileInfoTImpl.h | 8 +- dom/indexedDB/FileManager.h | 6 +- dom/indexedDB/FileManagerBase.h | 18 +- dom/indexedDB/IDBCursor.h | 6 +- dom/indexedDB/IDBObjectStore.cpp | 44 +- dom/indexedDB/IDBObjectStore.h | 3 +- dom/indexedDB/IndexedDatabase.cpp | 223 ++-- dom/indexedDB/IndexedDatabase.h | 129 +- dom/indexedDB/IndexedDatabaseInlines.h | 100 +- dom/indexedDB/IndexedDatabaseManager.cpp | 36 +- dom/indexedDB/IndexedDatabaseManager.h | 5 +- dom/indexedDB/InitializedOnce.h | 149 +++ dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh | 2 +- dom/indexedDB/SafeRefPtr.h | 185 --- dom/indexedDB/SerializationHelpers.h | 8 +- dom/indexedDB/moz.build | 2 +- dom/indexedDB/test/gtest/TestFileInfo.cpp | 12 +- 21 files changed, 971 insertions(+), 1189 deletions(-) create mode 100644 dom/indexedDB/InitializedOnce.h delete mode 100644 dom/indexedDB/SafeRefPtr.h diff --git a/dom/indexedDB/ActorsChild.cpp b/dom/indexedDB/ActorsChild.cpp index f50f66f69125..f36e492c9af1 100644 --- a/dom/indexedDB/ActorsChild.cpp +++ b/dom/indexedDB/ActorsChild.cpp @@ -519,17 +519,16 @@ auto DeserializeStructuredCloneFiles( MOZ_ASSERT_IF(aForPreprocess, aSerializedFiles.Length() == 1); const auto count = aSerializedFiles.Length(); - auto files = nsTArray(count); + auto files = nsTArray(count); for (const auto& serializedFile : aSerializedFiles) { - MOZ_ASSERT_IF( - aForPreprocess, - serializedFile.type() == StructuredCloneFileBase::eStructuredClone); + MOZ_ASSERT_IF(aForPreprocess, serializedFile.type() == + StructuredCloneFile::eStructuredClone); const BlobOrMutableFile& blobOrMutableFile = serializedFile.file(); switch (serializedFile.type()) { - case StructuredCloneFileBase::eBlob: { + case StructuredCloneFile::eBlob: { MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::TIPCBlob); const IPCBlob& ipcBlob = blobOrMutableFile.get_IPCBlob(); @@ -540,19 +539,19 @@ auto DeserializeStructuredCloneFiles( RefPtr blob = Blob::Create(aDatabase->GetOwnerGlobal(), blobImpl); MOZ_ASSERT(blob); - files.EmplaceBack(StructuredCloneFileBase::eBlob, std::move(blob)); + files.EmplaceBack(StructuredCloneFile::eBlob, std::move(blob)); break; } - case StructuredCloneFileBase::eMutableFile: { + case StructuredCloneFile::eMutableFile: { MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t || blobOrMutableFile.type() == BlobOrMutableFile::TPBackgroundMutableFileChild); switch (blobOrMutableFile.type()) { case BlobOrMutableFile::Tnull_t: { - files.EmplaceBack(StructuredCloneFileBase::eMutableFile); + files.EmplaceBack(StructuredCloneFile::eMutableFile); break; } @@ -582,7 +581,7 @@ auto DeserializeStructuredCloneFiles( break; } - case StructuredCloneFileBase::eStructuredClone: { + case StructuredCloneFile::eStructuredClone: { if (aForPreprocess) { MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::TIPCBlob); @@ -595,19 +594,19 @@ auto DeserializeStructuredCloneFiles( Blob::Create(aDatabase->GetOwnerGlobal(), blobImpl); MOZ_ASSERT(blob); - files.EmplaceBack(StructuredCloneFileBase::eStructuredClone, + files.EmplaceBack(StructuredCloneFile::eStructuredClone, std::move(blob)); } else { MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t); - files.EmplaceBack(StructuredCloneFileBase::eStructuredClone); + files.EmplaceBack(StructuredCloneFile::eStructuredClone); } break; } - case StructuredCloneFileBase::eWasmBytecode: - case StructuredCloneFileBase::eWasmCompiled: { + case StructuredCloneFile::eWasmBytecode: + case StructuredCloneFile::eWasmCompiled: { MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t); files.EmplaceBack(serializedFile.type()); @@ -1368,7 +1367,7 @@ class BackgroundRequestChild::PreprocessHelper final mActor = nullptr; } - nsresult Init(const StructuredCloneFileChild& aFile); + nsresult Init(const StructuredCloneFile& aFile); nsresult Dispatch(); @@ -2942,10 +2941,10 @@ mozilla::ipc::IPCResult BackgroundRequestChild::RecvPreprocess( } nsresult BackgroundRequestChild::PreprocessHelper::Init( - const StructuredCloneFileChild& aFile) { + const StructuredCloneFile& aFile) { AssertIsOnOwningThread(); MOZ_ASSERT(aFile.HasBlob()); - MOZ_ASSERT(aFile.Type() == StructuredCloneFileBase::eStructuredClone); + MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eStructuredClone); MOZ_ASSERT(mState == State::Initial); // The stream transport service is used for asynchronous processing. It has a @@ -3421,12 +3420,12 @@ void BackgroundCursorChild::SendDeleteMeInternal() { MOZ_ASSERT(!mStrongRequest); MOZ_ASSERT(!mStrongCursor); - mRequest.destroy(); + mRequest.reset(); mTransaction = nullptr; // TODO: The things until here could be pulled up to // BackgroundCursorChildBase. - mSource.destroy(); + mSource.reset(); if (mCursor) { mCursor->ClearBackgroundActor(); @@ -3677,9 +3676,9 @@ void BackgroundCursorChild::ActorDestroy(ActorDestroyReason aWhy) { } #ifdef DEBUG - mRequest.maybeDestroy(); + mRequest.maybeReset(); mTransaction = nullptr; - mSource.maybeDestroy(); + mSource.maybeReset(); #endif } diff --git a/dom/indexedDB/ActorsChild.h b/dom/indexedDB/ActorsChild.h index af0f61bf3fbc..1693b938e177 100644 --- a/dom/indexedDB/ActorsChild.h +++ b/dom/indexedDB/ActorsChild.h @@ -24,7 +24,6 @@ #include "mozilla/dom/PBackgroundFileHandleChild.h" #include "mozilla/dom/PBackgroundFileRequestChild.h" #include "mozilla/dom/PBackgroundMutableFileChild.h" -#include "mozilla/InitializedOnce.h" #include "mozilla/UniquePtr.h" #include "nsCOMPtr.h" #include "nsTArray.h" @@ -637,7 +636,7 @@ class BackgroundCursorChildBase : public PBackgroundIDBCursorChild { private: NS_DECL_OWNINGTHREAD protected: - InitializedOnceNotNull mRequest; + InitializedOnceMustBeTrue mRequest; IDBTransaction* mTransaction; // These are only set while a request is in progress. @@ -682,7 +681,7 @@ class BackgroundCursorChild final : public BackgroundCursorChildBase { friend class BackgroundTransactionChild; friend class BackgroundVersionChangeTransactionChild; - InitializedOnceNotNull mSource; + InitializedOnceMustBeTrue mSource; IDBCursorImpl* mCursor; std::deque> mCachedResponses, mDelayedResponses; diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 03c67b0c5045..5aa2b20652a0 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -17,6 +17,7 @@ #include "IndexedDatabase.h" #include "IndexedDatabaseInlines.h" #include "IndexedDatabaseManager.h" +#include "InitializedOnce.h" #include "js/StructuredClone.h" #include "js/Value.h" #include "jsapi.h" @@ -29,7 +30,6 @@ #include "mozilla/CycleCollectedJSRuntime.h" #include "mozilla/EndianUtils.h" #include "mozilla/ErrorNames.h" -#include "mozilla/InitializedOnce.h" #include "mozilla/JSObjectHolder.h" #include "mozilla/LazyIdleThread.h" #include "mozilla/Maybe.h" @@ -120,7 +120,6 @@ #include "prsystem.h" #include "prtime.h" #include "ReportInternalError.h" -#include "SafeRefPtr.h" #include "snappy/snappy.h" #define DISABLE_ASSERTS_FOR_FUZZING 0 @@ -421,7 +420,7 @@ struct FullDatabaseMetadata { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FullDatabaseMetadata) - MOZ_MUST_USE SafeRefPtr Duplicate() const; + MOZ_MUST_USE RefPtr Duplicate() const; private: ~FullDatabaseMetadata() = default; @@ -3415,7 +3414,7 @@ nsresult UpgradeSchemaFrom18_0To19_0(mozIStorageConnection* aConnection) { } class UpgradeFileIdsFunction final : public mozIStorageFunction { - SafeRefPtr mFileManager; + RefPtr mFileManager; public: UpgradeFileIdsFunction() { AssertIsOnIOThread(); } @@ -4719,9 +4718,9 @@ class DatabaseConnection final { class UpdateRefcountFunction; private: - InitializedOnceNotNull> + InitializedOnceMustBeTrue> mStorageConnection; - InitializedOnceNotNull> mFileManager; + InitializedOnceMustBeTrue> mFileManager; nsInterfaceHashtable mCachedStatements; RefPtr mUpdateRefcountFunction; @@ -4796,8 +4795,8 @@ class DatabaseConnection final { void EnableQuotaChecks(); private: - DatabaseConnection(nsCOMPtr aStorageConnection, - SafeRefPtr aFileManager); + DatabaseConnection(mozIStorageConnection* aStorageConnection, + FileManager* aFileManager); ~DatabaseConnection(); @@ -4882,7 +4881,7 @@ class DatabaseConnection::UpdateRefcountFunction final enum class UpdateType { Increment, Decrement }; DatabaseConnection* const mConnection; - FileManager& mFileManager; + FileManager* const mFileManager; nsClassHashtable mFileInfoEntries; nsDataHashtable mSavepointEntriesIndex; @@ -4897,7 +4896,7 @@ class DatabaseConnection::UpdateRefcountFunction final NS_DECL_MOZISTORAGEFUNCTION UpdateRefcountFunction(DatabaseConnection* aConnection, - FileManager& aFileManager); + FileManager* aFileManager); nsresult WillCommit(); @@ -4954,12 +4953,12 @@ class DatabaseConnection::UpdateRefcountFunction::DatabaseUpdateFunction final { }; class DatabaseConnection::UpdateRefcountFunction::FileInfoEntry final { - SafeRefPtr mFileInfo; + RefPtr mFileInfo; int32_t mDelta; int32_t mSavepointDelta; public: - explicit FileInfoEntry(SafeRefPtr aFileInfo) + explicit FileInfoEntry(RefPtr aFileInfo) : mFileInfo(std::move(aFileInfo)), mDelta(0), mSavepointDelta(0) { MOZ_COUNT_CTOR(DatabaseConnection::UpdateRefcountFunction::FileInfoEntry); } @@ -4977,7 +4976,7 @@ class DatabaseConnection::UpdateRefcountFunction::FileInfoEntry final { } } void DecBySavepointDelta() { mDelta -= mSavepointDelta; } - SafeRefPtr ReleaseFileInfo() { return std::move(mFileInfo); } + RefPtr ReleaseFileInfo() { return std::move(mFileInfo); } void MaybeUpdateDBRefs() { if (mDelta) { mFileInfo->UpdateDBRefs(mDelta); @@ -5042,7 +5041,7 @@ class ConnectionPool final { NS_ASSERT_OWNINGTHREAD(ConnectionPool); } - nsresult GetOrCreateConnection(const Database& aDatabase, + nsresult GetOrCreateConnection(const Database* aDatabase, RefPtr* aConnection); uint64_t Start(const nsID& aBackgroundChildLoggingId, @@ -5308,7 +5307,7 @@ struct ConnectionPool::IdleResource { }; struct ConnectionPool::IdleDatabaseInfo final : public IdleResource { - InitializedOnceNotNull mDatabaseInfo; + InitializedOnceMustBeTrue mDatabaseInfo; public: explicit IdleDatabaseInfo(DatabaseInfo* aDatabaseInfo); @@ -5590,7 +5589,7 @@ class DatabaseOperationBase : public Runnable, const nsCString& aLocale); static nsresult GetUniqueIndexTableForObjectStore( - TransactionBase& aTransaction, IndexOrObjectStoreId aObjectStoreId, + TransactionBase* aTransaction, IndexOrObjectStoreId aObjectStoreId, Maybe& aMaybeUniqueIndexTable); static nsresult IndexDataValuesFromUpdateInfos( @@ -5681,7 +5680,7 @@ class TransactionDatabaseOperationBase : public DatabaseOperationBase { Completed }; - InitializedOnceNotNull> mTransaction; + InitializedOnce> mTransaction; InternalState mInternalState = InternalState::Initial; bool mWaitingForContinue = false; const bool mTransactionIsAborted; @@ -5735,7 +5734,7 @@ class TransactionDatabaseOperationBase : public DatabaseOperationBase { // May be overridden by subclasses if they need to perform work on the // background thread before being dispatched. Returning false will kill the // child actors and prevent dispatch. - virtual bool Init(TransactionBase& aTransaction); + virtual bool Init(TransactionBase* aTransaction); // This callback will be called on the background thread before releasing the // final reference to this request object. Subclasses may perform any @@ -5744,9 +5743,9 @@ class TransactionDatabaseOperationBase : public DatabaseOperationBase { protected: explicit TransactionDatabaseOperationBase( - SafeRefPtr aTransaction); + RefPtr aTransaction); - TransactionDatabaseOperationBase(SafeRefPtr aTransaction, + TransactionDatabaseOperationBase(RefPtr aTransaction, uint64_t aLoggingSerialNumber); ~TransactionDatabaseOperationBase() override; @@ -5895,8 +5894,8 @@ class Database final private: RefPtr mFactory; - SafeRefPtr mMetadata; - SafeRefPtr mFileManager; + RefPtr mMetadata; + RefPtr mFileManager; RefPtr mDirectoryLock; nsTHashtable> mTransactions; nsTHashtable> mMutableFiles; @@ -5929,8 +5928,8 @@ class Database final Database(RefPtr aFactory, const PrincipalInfo& aPrincipalInfo, const Maybe& aOptionalContentParentId, const nsACString& aGroup, const nsACString& aOrigin, - uint32_t aTelemetryId, SafeRefPtr aMetadata, - SafeRefPtr aFileManager, + uint32_t aTelemetryId, RefPtr aMetadata, + RefPtr aFileManager, RefPtr aDirectoryLock, bool aFileHandleDisabled, bool aChromeWriteAccessAllowed); @@ -5970,21 +5969,11 @@ class Database final const nsString& FilePath() const { return mFilePath; } - FileManager& GetFileManager() const { return *mFileManager; } + FileManager* GetFileManager() const { return mFileManager; } - SafeRefPtr GetFileManagerPtr() const { - MOZ_ASSERT(mFileManager); - return mFileManager.clonePtr(); - } - - const FullDatabaseMetadata& Metadata() const { + FullDatabaseMetadata* Metadata() const { MOZ_ASSERT(mMetadata); - return *mMetadata; - } - - SafeRefPtr MetadataPtr() const { - MOZ_ASSERT(mMetadata); - return mMetadata.clonePtr(); + return mMetadata; } PBackgroundParent* GetBackgroundParent() const { @@ -6001,9 +5990,9 @@ class Database final return mFactory->GetLoggingInfo(); } - bool RegisterTransaction(TransactionBase& aTransaction); + bool RegisterTransaction(TransactionBase* aTransaction); - void UnregisterTransaction(TransactionBase& aTransaction); + void UnregisterTransaction(TransactionBase* aTransaction); bool IsFileHandleDisabled() const { return mFileHandleDisabled; } @@ -6021,7 +6010,7 @@ class Database final void SetActorAlive(); - void MapBlob(const IPCBlob& aIPCBlob, SafeRefPtr aFileInfo); + void MapBlob(const IPCBlob& aIPCBlob, RefPtr aFileInfo); bool IsActorAlive() const { AssertIsOnBackgroundThread(); @@ -6071,7 +6060,7 @@ class Database final mFactory.forget()); } - MOZ_MUST_USE SafeRefPtr GetBlob(const IPCBlob& aID); + MOZ_MUST_USE RefPtr GetBlob(const IPCBlob& aID); void UnmapBlob(const nsID& aID); @@ -6146,7 +6135,7 @@ class Database::StartTransactionOp final friend class Database; private: - explicit StartTransactionOp(SafeRefPtr aTransaction) + explicit StartTransactionOp(RefPtr aTransaction) : TransactionDatabaseOperationBase(std::move(aTransaction), /* aLoggingSerialNumber */ 0) {} @@ -6165,11 +6154,10 @@ class Database::StartTransactionOp final class Database::UnmapBlobCallback final : public IPCBlobInputStreamParentCallback { - SafeRefPtr mDatabase; + RefPtr mDatabase; public: - explicit UnmapBlobCallback(SafeRefPtr aDatabase) - : mDatabase(std::move(aDatabase)) { + explicit UnmapBlobCallback(Database* aDatabase) : mDatabase(aDatabase) { AssertIsOnBackgroundThread(); } @@ -6179,7 +6167,7 @@ class Database::UnmapBlobCallback final AssertIsOnBackgroundThread(); MOZ_ASSERT(mDatabase); - const SafeRefPtr database = std::move(mDatabase); + const RefPtr database = std::move(mDatabase); database->UnmapBlob(aID); } @@ -6225,21 +6213,15 @@ class DatabaseFile final : public PBackgroundIDBDatabaseFileParent { // - Cleared on the connection thread once the file has successfully been // written to disk. InitializedOnce> mBlobImpl; - const SafeRefPtr mFileInfo; + const RefPtr mFileInfo; public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::dom::indexedDB::DatabaseFile); - const FileInfo& GetFileInfo() const { + const RefPtr& GetFileInfo() const { AssertIsOnBackgroundThread(); - return *mFileInfo; - } - - SafeRefPtr GetFileInfoPtr() const { - AssertIsOnBackgroundThread(); - - return mFileInfo.clonePtr(); + return mFileInfo; } /** @@ -6260,20 +6242,20 @@ class DatabaseFile final : public PBackgroundIDBDatabaseFileParent { MOZ_ASSERT(!IsOnBackgroundThread()); MOZ_ASSERT(*mBlobImpl); - mBlobImpl.destroy(); + mBlobImpl.reset(); } public: // Called when sending to the child. - explicit DatabaseFile(SafeRefPtr aFileInfo) - : mBlobImpl{nullptr}, mFileInfo(std::move(aFileInfo)) { + explicit DatabaseFile(FileInfo* aFileInfo) + : mBlobImpl{nullptr}, mFileInfo(aFileInfo) { AssertIsOnBackgroundThread(); MOZ_ASSERT(mFileInfo); } // Called when receiving from the child. - DatabaseFile(RefPtr aBlobImpl, SafeRefPtr aFileInfo) - : mBlobImpl(std::move(aBlobImpl)), mFileInfo(std::move(aFileInfo)) { + DatabaseFile(BlobImpl* aBlobImpl, FileInfo* aFileInfo) + : mBlobImpl(aBlobImpl), mFileInfo(aFileInfo) { AssertIsOnBackgroundThread(); MOZ_ASSERT(*mBlobImpl); MOZ_ASSERT(mFileInfo); @@ -6319,10 +6301,10 @@ class TransactionBase { typedef IDBTransaction::Mode Mode; private: - const SafeRefPtr mDatabase; + const RefPtr mDatabase; nsTArray> mModifiedAutoIncrementObjectStoreMetadataArray; - LazyInitializedOnceNotNull mTransactionId; + InitializedOnceMustBeTrue mTransactionId; const nsCString mDatabaseId; const int64_t mLoggingSerialNumber; uint64_t mActiveRequestCount; @@ -6338,7 +6320,8 @@ class TransactionBase { FlippedOnce mCommitOrAbortReceived; FlippedOnce mCommittedOrAborted; FlippedOnce mForceAborted; - LazyInitializedOnce> mLastRequestBeforeCommit; + InitializedOnce, LazyInit::Allow> + mLastRequestBeforeCommit; Maybe mLastFailedRequest; public: @@ -6388,22 +6371,10 @@ class TransactionBase { Mode GetMode() const { return mMode; } - const Database& GetDatabase() const { + Database* GetDatabase() const { MOZ_ASSERT(mDatabase); - return *mDatabase; - } - - Database& GetMutableDatabase() const { - MOZ_ASSERT(mDatabase); - - return *mDatabase; - } - - SafeRefPtr GetDatabasePtr() const { - MOZ_ASSERT(mDatabase); - - return mDatabase.clonePtr(); + return mDatabase; } DatabaseLoggingInfo* GetLoggingInfo() const { @@ -6432,7 +6403,7 @@ class TransactionBase { AssertIsOnBackgroundThread(); MOZ_ASSERT(!IsActorDestroyed()); - return GetDatabase().GetBackgroundParent(); + return GetDatabase()->GetBackgroundParent(); } void NoteModifiedAutoIncrementObjectStore(FullObjectStoreMetadata* aMetadata); @@ -6447,7 +6418,7 @@ class TransactionBase { void Invalidate(); protected: - TransactionBase(SafeRefPtr aDatabase, Mode aMode); + TransactionBase(Database* aDatabase, Mode aMode); virtual ~TransactionBase(); @@ -6525,14 +6496,14 @@ class TransactionBase::CommitOp final : public DatabaseOperationBase, public ConnectionPool::FinishCallback { friend class TransactionBase; - SafeRefPtr mTransaction; + RefPtr mTransaction; nsresult mResultCode; ///< TODO: There is also a mResultCode in ///< DatabaseOperationBase. Is there a reason not to ///< use that? At least a more specific name should be ///< given to this one. private: - CommitOp(SafeRefPtr aTransaction, nsresult aResultCode); + CommitOp(TransactionBase* aTransaction, nsresult aResultCode); ~CommitOp() override = default; @@ -6570,7 +6541,7 @@ class NormalTransaction final : public TransactionBase, private: // This constructor is only called by Database. - NormalTransaction(SafeRefPtr aDatabase, TransactionBase::Mode aMode, + NormalTransaction(Database* aDatabase, TransactionBase::Mode aMode, nsTArray>& aObjectStores); // Reference counted. @@ -6618,15 +6589,14 @@ class VersionChangeTransaction final friend class OpenDatabaseOp; RefPtr mOpenDatabaseOp; - SafeRefPtr mOldMetadata; + RefPtr mOldMetadata; FlippedOnce mActorWasAlive; - public: + private: // Only called by OpenDatabaseOp. explicit VersionChangeTransaction(OpenDatabaseOp* aOpenDatabaseOp); - private: // Reference counted. ~VersionChangeTransaction() override; @@ -6697,13 +6667,13 @@ class VersionChangeTransaction final }; class MutableFile : public BackgroundMutableFileParentBase { - const SafeRefPtr mDatabase; - const SafeRefPtr mFileInfo; + const RefPtr mDatabase; + const RefPtr mFileInfo; public: - static MOZ_MUST_USE RefPtr Create( - nsIFile* aFile, SafeRefPtr aDatabase, - SafeRefPtr aFileInfo); + static MOZ_MUST_USE RefPtr Create(nsIFile* aFile, + Database* aDatabase, + RefPtr aFileInfo); const Database& GetDatabase() const { AssertIsOnBackgroundThread(); @@ -6711,10 +6681,10 @@ class MutableFile : public BackgroundMutableFileParentBase { return *mDatabase; } - SafeRefPtr GetFileInfoPtr() const { + const RefPtr& GetFileInfo() const { AssertIsOnBackgroundThread(); - return mFileInfo.clonePtr(); + return mFileInfo; } void NoteActiveState() override; @@ -6728,8 +6698,8 @@ class MutableFile : public BackgroundMutableFileParentBase { already_AddRefed CreateBlobImpl() override; private: - MutableFile(nsIFile* aFile, SafeRefPtr aDatabase, - SafeRefPtr aFileInfo); + MutableFile(nsIFile* aFile, RefPtr aDatabase, + RefPtr aFileInfo); ~MutableFile() override; @@ -6912,7 +6882,7 @@ class FactoryOp void FinishSendResults(); nsresult SendVersionChangeMessages(DatabaseActorInfo* aDatabaseActorInfo, - Maybe aOpeningDatabase, + Database* aOpeningDatabase, uint64_t aOldVersion, const Maybe& aNewVersion); @@ -6966,15 +6936,12 @@ class FactoryOp }; struct FactoryOp::MaybeBlockedDatabaseInfo final { - SafeRefPtr mDatabase; + RefPtr mDatabase; bool mBlocked; - MaybeBlockedDatabaseInfo(MaybeBlockedDatabaseInfo&&) = default; - MaybeBlockedDatabaseInfo& operator=(MaybeBlockedDatabaseInfo&&) = default; - - MOZ_IMPLICIT MaybeBlockedDatabaseInfo(SafeRefPtr aDatabase) - : mDatabase(std::move(aDatabase)), mBlocked(false) { - MOZ_ASSERT(mDatabase); + MOZ_IMPLICIT MaybeBlockedDatabaseInfo(Database* aDatabase) + : mDatabase(aDatabase), mBlocked(false) { + MOZ_ASSERT(aDatabase); MOZ_COUNT_CTOR(FactoryOp::MaybeBlockedDatabaseInfo); } @@ -6983,11 +6950,11 @@ struct FactoryOp::MaybeBlockedDatabaseInfo final { MOZ_COUNT_DTOR(FactoryOp::MaybeBlockedDatabaseInfo); } - bool operator==(Database* aOther) const { return mDatabase == aOther; } - - Database* operator->() const& MOZ_NO_ADDREF_RELEASE_ON_RETURN { - return mDatabase.unsafeGetRawPtr(); + bool operator==(const MaybeBlockedDatabaseInfo& aOther) const { + return mDatabase == aOther.mDatabase; } + + Database* operator->() MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mDatabase; } }; class OpenDatabaseOp final : public FactoryOp { @@ -6998,13 +6965,13 @@ class OpenDatabaseOp final : public FactoryOp { Maybe mOptionalContentParentId; - SafeRefPtr mMetadata; + RefPtr mMetadata; uint64_t mRequestedVersion; - SafeRefPtr mFileManager; + RefPtr mFileManager; - SafeRefPtr mDatabase; - SafeRefPtr mVersionChangeTransaction; + RefPtr mDatabase; + RefPtr mVersionChangeTransaction; // This is only set while a VersionChangeOp is live. It holds a strong // reference to its OpenDatabaseOp object so this is a weak pointer to avoid @@ -7030,7 +6997,7 @@ class OpenDatabaseOp final : public FactoryOp { void MetadataToSpec(DatabaseSpec& aSpec); - void AssertMetadataConsistency(const FullDatabaseMetadata& aMetadata) + void AssertMetadataConsistency(const FullDatabaseMetadata* aMetadata) #ifdef DEBUG ; #else @@ -7072,7 +7039,7 @@ class OpenDatabaseOp::VersionChangeOp final private: explicit VersionChangeOp(OpenDatabaseOp* aOpenDatabaseOp) : TransactionDatabaseOperationBase( - aOpenDatabaseOp->mVersionChangeTransaction.clonePtr(), + aOpenDatabaseOp->mVersionChangeTransaction, aOpenDatabaseOp->LoggingSerialNumber()), mOpenDatabaseOp(aOpenDatabaseOp), mRequestedVersion(aOpenDatabaseOp->mRequestedVersion), @@ -7154,7 +7121,7 @@ class DeleteDatabaseOp::VersionChangeOp final : public DatabaseOperationBase { class DatabaseOp : public DatabaseOperationBase, public PBackgroundIDBDatabaseRequestParent { protected: - SafeRefPtr mDatabase; + RefPtr mDatabase; enum class State { // Just created on the PBackground thread, dispatched to the main thread. @@ -7183,7 +7150,7 @@ class DatabaseOp : public DatabaseOperationBase, } protected: - DatabaseOp(SafeRefPtr aDatabase); + DatabaseOp(Database* aDatabase); ~DatabaseOp() override { MOZ_ASSERT_IF(OperationMayProceed(), @@ -7208,11 +7175,10 @@ class DatabaseOp : public DatabaseOperationBase, class CreateFileOp final : public DatabaseOp { const CreateFileParams mParams; - LazyInitializedOnce> mFileInfo; + InitializedOnce, LazyInit::Allow> mFileInfo; public: - CreateFileOp(SafeRefPtr aDatabase, - const DatabaseRequestParams& aParams); + CreateFileOp(Database* aDatabase, const DatabaseRequestParams& aParams); private: ~CreateFileOp() override = default; @@ -7230,7 +7196,7 @@ class VersionChangeTransactionOp : public TransactionDatabaseOperationBase { protected: explicit VersionChangeTransactionOp( - SafeRefPtr aTransaction) + RefPtr aTransaction) : TransactionDatabaseOperationBase(std::move(aTransaction)) {} ~VersionChangeTransactionOp() override = default; @@ -7248,7 +7214,7 @@ class CreateObjectStoreOp final : public VersionChangeTransactionOp { private: // Only created by VersionChangeTransaction. - CreateObjectStoreOp(SafeRefPtr aTransaction, + CreateObjectStoreOp(RefPtr aTransaction, const ObjectStoreMetadata& aMetadata) : VersionChangeTransactionOp(std::move(aTransaction)), mMetadata(aMetadata) { @@ -7268,7 +7234,7 @@ class DeleteObjectStoreOp final : public VersionChangeTransactionOp { private: // Only created by VersionChangeTransaction. - DeleteObjectStoreOp(SafeRefPtr aTransaction, + DeleteObjectStoreOp(RefPtr aTransaction, FullObjectStoreMetadata* const aMetadata, const bool aIsLastObjectStore) : VersionChangeTransactionOp(std::move(aTransaction)), @@ -7290,7 +7256,7 @@ class RenameObjectStoreOp final : public VersionChangeTransactionOp { private: // Only created by VersionChangeTransaction. - RenameObjectStoreOp(SafeRefPtr aTransaction, + RenameObjectStoreOp(RefPtr aTransaction, FullObjectStoreMetadata* const aMetadata) : VersionChangeTransactionOp(std::move(aTransaction)), mId(aMetadata->mCommonMetadata.id()), @@ -7310,13 +7276,13 @@ class CreateIndexOp final : public VersionChangeTransactionOp { const IndexMetadata mMetadata; Maybe mMaybeUniqueIndexTable; - const SafeRefPtr mFileManager; + const RefPtr mFileManager; const nsCString mDatabaseId; const IndexOrObjectStoreId mObjectStoreId; private: // Only created by VersionChangeTransaction. - CreateIndexOp(SafeRefPtr aTransaction, + CreateIndexOp(RefPtr aTransaction, IndexOrObjectStoreId aObjectStoreId, const IndexMetadata& aMetadata); @@ -7326,7 +7292,7 @@ class CreateIndexOp final : public VersionChangeTransactionOp { nsresult InsertDataFromObjectStoreInternal(DatabaseConnection* aConnection); - bool Init(TransactionBase& aTransaction) override; + bool Init(TransactionBase* aTransaction) override; nsresult DoDatabaseWork(DatabaseConnection* aConnection) override; }; @@ -7363,7 +7329,7 @@ class DeleteIndexOp final : public VersionChangeTransactionOp { private: // Only created by VersionChangeTransaction. - DeleteIndexOp(SafeRefPtr aTransaction, + DeleteIndexOp(RefPtr aTransaction, IndexOrObjectStoreId aObjectStoreId, IndexOrObjectStoreId aIndexId, const bool aUnique, const bool aIsLastIndex); @@ -7386,7 +7352,7 @@ class RenameIndexOp final : public VersionChangeTransactionOp { private: // Only created by VersionChangeTransaction. - RenameIndexOp(SafeRefPtr aTransaction, + RenameIndexOp(RefPtr aTransaction, FullIndexMetadata* const aMetadata, IndexOrObjectStoreId aObjectStoreId) : VersionChangeTransactionOp(std::move(aTransaction)), @@ -7411,7 +7377,7 @@ class NormalTransactionOp : public TransactionDatabaseOperationBase, void Cleanup() override; protected: - explicit NormalTransactionOp(SafeRefPtr aTransaction) + explicit NormalTransactionOp(RefPtr aTransaction) : TransactionDatabaseOperationBase(std::move(aTransaction)) #ifdef DEBUG , @@ -7477,14 +7443,14 @@ class ObjectStoreAddOrPutRequestOp final : public NormalTransactionOp { private: // Only created by TransactionBase. - ObjectStoreAddOrPutRequestOp(SafeRefPtr aTransaction, + ObjectStoreAddOrPutRequestOp(RefPtr aTransaction, RequestParams&& aParams); ~ObjectStoreAddOrPutRequestOp() override = default; nsresult RemoveOldIndexDataValues(DatabaseConnection* aConnection); - bool Init(TransactionBase& aTransaction) override; + bool Init(TransactionBase* aTransaction) override; nsresult DoDatabaseWork(DatabaseConnection* aConnection) override; @@ -7494,21 +7460,21 @@ class ObjectStoreAddOrPutRequestOp final : public NormalTransactionOp { }; class ObjectStoreAddOrPutRequestOp::StoredFileInfo final { - InitializedOnceNotNull> mFileInfo; + InitializedOnceMustBeTrue> mFileInfo; // Either nothing, a file actor or a non-Blob-backed inputstream to write to // disk. using FileActorOrInputStream = Variant, nsCOMPtr>; InitializedOnce mFileActorOrInputStream; #ifdef DEBUG - const StructuredCloneFileBase::FileType mType; + const StructuredCloneFile::FileType mType; #endif void AssertInvariants() const { // The only allowed types are eStructuredClone, eBlob and eMutableFile. - MOZ_ASSERT(StructuredCloneFileBase::eStructuredClone == mType || - StructuredCloneFileBase::eBlob == mType || - StructuredCloneFileBase::eMutableFile == mType); + MOZ_ASSERT(StructuredCloneFile::eStructuredClone == mType || + StructuredCloneFile::eBlob == mType || + StructuredCloneFile::eMutableFile == mType); // mFileInfo and a file actor in mFileActorOrInputStream are present until // the object is moved away, but an inputStream in mFileActorOrInputStream @@ -7523,7 +7489,7 @@ class ObjectStoreAddOrPutRequestOp::StoredFileInfo final { // storedFileInfo.mFileActorOrInputStream CAN be a non-nullptr input // stream (but that might have been release by ReleaseInputStream). MOZ_ASSERT_IF( - StructuredCloneFileBase::eStructuredClone == mType, + StructuredCloneFile::eStructuredClone == mType, !mFileActorOrInputStream || (mFileActorOrInputStream->is>() && mFileActorOrInputStream->as>())); @@ -7532,23 +7498,23 @@ class ObjectStoreAddOrPutRequestOp::StoredFileInfo final { // already been written to disk. storedFileInfo.mFileActorOrInputStream // MUST be a non-null file actor, but its GetInputStream may return // nullptr (so don't assert on that). - MOZ_ASSERT_IF(StructuredCloneFileBase::eBlob == mType, + MOZ_ASSERT_IF(StructuredCloneFile::eBlob == mType, mFileActorOrInputStream->is>() && mFileActorOrInputStream->as>()); // - It's a mutable file (eMutableFile). No writing will be performed, // and storedFileInfo.mFileActorOrInputStream is Nothing. - MOZ_ASSERT_IF(StructuredCloneFileBase::eMutableFile == mType, + MOZ_ASSERT_IF(StructuredCloneFile::eMutableFile == mType, mFileActorOrInputStream->is()); } } - explicit StoredFileInfo(SafeRefPtr aFileInfo) + explicit StoredFileInfo(RefPtr aFileInfo) : mFileInfo{std::move(aFileInfo)}, mFileActorOrInputStream { Nothing {} } #ifdef DEBUG - , mType { StructuredCloneFileBase::eMutableFile } + , mType { StructuredCloneFile::eMutableFile } #endif { AssertIsOnBackgroundThread(); @@ -7557,13 +7523,12 @@ class ObjectStoreAddOrPutRequestOp::StoredFileInfo final { MOZ_COUNT_CTOR(ObjectStoreAddOrPutRequestOp::StoredFileInfo); } - StoredFileInfo(SafeRefPtr aFileInfo, - RefPtr aFileActor) + StoredFileInfo(RefPtr aFileInfo, RefPtr aFileActor) : mFileInfo{std::move(aFileInfo)}, mFileActorOrInputStream { std::move(aFileActor) } #ifdef DEBUG - , mType { StructuredCloneFileBase::eBlob } + , mType { StructuredCloneFile::eBlob } #endif { AssertIsOnBackgroundThread(); @@ -7572,13 +7537,13 @@ class ObjectStoreAddOrPutRequestOp::StoredFileInfo final { MOZ_COUNT_CTOR(ObjectStoreAddOrPutRequestOp::StoredFileInfo); } - StoredFileInfo(SafeRefPtr aFileInfo, + StoredFileInfo(RefPtr aFileInfo, nsCOMPtr aInputStream) : mFileInfo{std::move(aFileInfo)}, mFileActorOrInputStream { std::move(aInputStream) } #ifdef DEBUG - , mType { StructuredCloneFileBase::eStructuredClone } + , mType { StructuredCloneFile::eStructuredClone } #endif { AssertIsOnBackgroundThread(); @@ -7602,15 +7567,15 @@ class ObjectStoreAddOrPutRequestOp::StoredFileInfo final { StoredFileInfo(StoredFileInfo&&) = default; #endif - static StoredFileInfo CreateForMutableFile(SafeRefPtr aFileInfo) { + static StoredFileInfo CreateForMutableFile(RefPtr aFileInfo) { return StoredFileInfo{std::move(aFileInfo)}; } - static StoredFileInfo CreateForBlob(SafeRefPtr aFileInfo, + static StoredFileInfo CreateForBlob(RefPtr aFileInfo, RefPtr aFileActor) { return {std::move(aFileInfo), std::move(aFileActor)}; } static StoredFileInfo CreateForStructuredClone( - SafeRefPtr aFileInfo, nsCOMPtr aInputStream) { + RefPtr aFileInfo, nsCOMPtr aInputStream) { return {std::move(aFileInfo), std::move(aInputStream)}; } @@ -7636,7 +7601,7 @@ class ObjectStoreAddOrPutRequestOp::StoredFileInfo final { // called after GetInputStream, when mFileActorOrInputStream has been // cleared, which is only possible for this type. const bool res = !mFileActorOrInputStream; - MOZ_ASSERT(res == (StructuredCloneFileBase::eStructuredClone == mType)); + MOZ_ASSERT(res == (StructuredCloneFile::eStructuredClone == mType)); return res; } @@ -7656,7 +7621,7 @@ class ObjectStoreAddOrPutRequestOp::StoredFileInfo final { using InputStreamResult = mozilla::Result, nsresult>; InputStreamResult GetInputStream() { if (!mFileActorOrInputStream) { - MOZ_ASSERT(StructuredCloneFileBase::eStructuredClone == mType); + MOZ_ASSERT(StructuredCloneFile::eStructuredClone == mType); return nsCOMPtr{}; } @@ -7679,7 +7644,7 @@ class ObjectStoreAddOrPutRequestOp::StoredFileInfo final { auto res = inputStream; // reset() clears the inputStream parameter, so we needed to make a // copy before - mFileActorOrInputStream.destroy(); + mFileActorOrInputStream.reset(); AssertInvariants(); return res; }); @@ -7738,7 +7703,7 @@ class ObjectStoreGetRequestOp final : public NormalTransactionOp { friend class TransactionBase; const IndexOrObjectStoreId mObjectStoreId; - SafeRefPtr mDatabase; + RefPtr mDatabase; const Maybe mOptionalKeyRange; AutoTArray mResponse; PBackgroundParent* mBackgroundParent; @@ -7748,7 +7713,7 @@ class ObjectStoreGetRequestOp final : public NormalTransactionOp { private: // Only created by TransactionBase. - ObjectStoreGetRequestOp(SafeRefPtr aTransaction, + ObjectStoreGetRequestOp(RefPtr aTransaction, const RequestParams& aParams, bool aGetAll); ~ObjectStoreGetRequestOp() override = default; @@ -7776,7 +7741,7 @@ class ObjectStoreGetKeyRequestOp final : public NormalTransactionOp { private: // Only created by TransactionBase. - ObjectStoreGetKeyRequestOp(SafeRefPtr aTransaction, + ObjectStoreGetKeyRequestOp(RefPtr aTransaction, const RequestParams& aParams, bool aGetAll); ~ObjectStoreGetKeyRequestOp() override = default; @@ -7794,7 +7759,7 @@ class ObjectStoreDeleteRequestOp final : public NormalTransactionOp { bool mObjectStoreMayHaveIndexes; private: - ObjectStoreDeleteRequestOp(SafeRefPtr aTransaction, + ObjectStoreDeleteRequestOp(RefPtr aTransaction, const ObjectStoreDeleteParams& aParams); ~ObjectStoreDeleteRequestOp() override = default; @@ -7815,7 +7780,7 @@ class ObjectStoreClearRequestOp final : public NormalTransactionOp { bool mObjectStoreMayHaveIndexes; private: - ObjectStoreClearRequestOp(SafeRefPtr aTransaction, + ObjectStoreClearRequestOp(RefPtr aTransaction, const ObjectStoreClearParams& aParams); ~ObjectStoreClearRequestOp() override = default; @@ -7835,7 +7800,7 @@ class ObjectStoreCountRequestOp final : public NormalTransactionOp { ObjectStoreCountResponse mResponse; private: - ObjectStoreCountRequestOp(SafeRefPtr aTransaction, + ObjectStoreCountRequestOp(RefPtr aTransaction, const ObjectStoreCountParams& aParams) : NormalTransactionOp(std::move(aTransaction)), mParams(aParams) {} @@ -7854,7 +7819,7 @@ class IndexRequestOpBase : public NormalTransactionOp { const RefPtr mMetadata; protected: - IndexRequestOpBase(SafeRefPtr aTransaction, + IndexRequestOpBase(RefPtr aTransaction, const RequestParams& aParams) : NormalTransactionOp(std::move(aTransaction)), mMetadata(IndexMetadataForParams(Transaction(), aParams)) {} @@ -7869,16 +7834,16 @@ class IndexRequestOpBase : public NormalTransactionOp { class IndexGetRequestOp final : public IndexRequestOpBase { friend class TransactionBase; - SafeRefPtr mDatabase; + RefPtr mDatabase; const Maybe mOptionalKeyRange; - AutoTArray mResponse; + AutoTArray mResponse; PBackgroundParent* mBackgroundParent; const uint32_t mLimit; const bool mGetAll; private: // Only created by TransactionBase. - IndexGetRequestOp(SafeRefPtr aTransaction, + IndexGetRequestOp(RefPtr aTransaction, const RequestParams& aParams, bool aGetAll); ~IndexGetRequestOp() override = default; @@ -7898,7 +7863,7 @@ class IndexGetKeyRequestOp final : public IndexRequestOpBase { private: // Only created by TransactionBase. - IndexGetKeyRequestOp(SafeRefPtr aTransaction, + IndexGetKeyRequestOp(RefPtr aTransaction, const RequestParams& aParams, bool aGetAll); ~IndexGetKeyRequestOp() override = default; @@ -7916,7 +7881,7 @@ class IndexCountRequestOp final : public IndexRequestOpBase { private: // Only created by TransactionBase. - IndexCountRequestOp(SafeRefPtr aTransaction, + IndexCountRequestOp(RefPtr aTransaction, const RequestParams& aParams) : IndexRequestOpBase(std::move(aTransaction), aParams), mParams(aParams.get_IndexCountParams()) {} @@ -7976,17 +7941,17 @@ class CursorBase : public PBackgroundIDBCursorParent { friend class CommonOpenOpHelper; protected: - const SafeRefPtr mTransaction; + const RefPtr mTransaction; // This should only be touched on the PBackground thread to check whether // the objectStore has been deleted. Holding these saves a hash lookup for // every call to continue()/advance(). - InitializedOnceNotNull> + InitializedOnceMustBeTrue> mObjectStoreMetadata; const IndexOrObjectStoreId mObjectStoreId; - LazyInitializedOnce + InitializedOnce mLocaleAwareRangeBound; ///< If the cursor is based on a key range, the ///< bound in the direction of iteration (e.g. ///< the upper bound in case of mDirection == @@ -8005,7 +7970,7 @@ class CursorBase : public PBackgroundIDBCursorParent { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::dom::indexedDB::CursorBase) - CursorBase(SafeRefPtr aTransaction, + CursorBase(RefPtr aTransaction, RefPtr aObjectStoreMetadata, Direction aDirection, ConstructFromTransactionBase aConstructionTag); @@ -8022,7 +7987,7 @@ class IndexCursorBase : public CursorBase { public: bool IsLocaleAware() const { return !mLocale.IsEmpty(); } - IndexCursorBase(SafeRefPtr aTransaction, + IndexCursorBase(RefPtr aTransaction, RefPtr aObjectStoreMetadata, RefPtr aIndexMetadata, Direction aDirection, @@ -8040,7 +8005,7 @@ class IndexCursorBase : public CursorBase { // This should only be touched on the PBackground thread to check whether // the index has been deleted. Holding these saves a hash lookup for every // call to continue()/advance(). - InitializedOnceNotNull> mIndexMetadata; + InitializedOnceMustBeTrue> mIndexMetadata; const IndexOrObjectStoreId mIndexId; const bool mUniqueIndex; const nsCString @@ -8081,7 +8046,7 @@ class ObjectStoreCursorBase : public CursorBase { }; }; -using FilesArray = nsTArray>; +using FilesArray = nsTArray>; struct PseudoFilesArray { static constexpr bool IsEmpty() { return true; } @@ -8100,8 +8065,8 @@ class ValueCursorBase { protected: explicit ValueCursorBase(TransactionBase* const aTransaction) - : mDatabase(aTransaction->GetDatabasePtr()), - mFileManager(mDatabase->GetFileManagerPtr()), + : mDatabase(aTransaction->GetDatabase()), + mFileManager(mDatabase->GetFileManager()), mBackgroundParent(aTransaction->GetBackgroundParent()) { MOZ_ASSERT(mDatabase); MOZ_ASSERT(mFileManager); @@ -8111,10 +8076,10 @@ class ValueCursorBase { ~ValueCursorBase() { MOZ_ASSERT(!mBackgroundParent); } - const SafeRefPtr mDatabase; - const SafeRefPtr mFileManager; + const RefPtr mDatabase; + const RefPtr mFileManager; - InitializedOnceNotNull mBackgroundParent; + InitializedOnceMustBeTrue mBackgroundParent; }; class KeyCursorBase { @@ -8171,7 +8136,8 @@ class Cursor final CursorOpBase* mCurrentlyRunningOp = nullptr; - LazyInitializedOnce mContinueQueries; + InitializedOnce + mContinueQueries; // Only called by TransactionBase. bool Start(const OpenCursorParams& aParams) final; @@ -8192,22 +8158,22 @@ class Cursor final const Key& aCurrentObjectStoreKey) override; public: - Cursor(SafeRefPtr aTransaction, + Cursor(RefPtr aTransaction, RefPtr aObjectStoreMetadata, RefPtr aIndexMetadata, typename Base::Direction aDirection, typename Base::ConstructFromTransactionBase aConstructionTag) : Base{std::move(aTransaction), std::move(aObjectStoreMetadata), std::move(aIndexMetadata), aDirection, aConstructionTag}, - KeyValueBase{mTransaction.unsafeGetRawPtr()} {} + KeyValueBase{mTransaction} {} - Cursor(SafeRefPtr aTransaction, + Cursor(RefPtr aTransaction, RefPtr aObjectStoreMetadata, typename Base::Direction aDirection, typename Base::ConstructFromTransactionBase aConstructionTag) : Base{std::move(aTransaction), std::move(aObjectStoreMetadata), aDirection, aConstructionTag}, - KeyValueBase{mTransaction.unsafeGetRawPtr()} {} + KeyValueBase{mTransaction} {} private: void SetOptionalKeyRange(const Maybe& aOptionalKeyRange, @@ -8237,7 +8203,7 @@ class Cursor::CursorOpBase protected: explicit CursorOpBase(Cursor* aCursor) - : TransactionDatabaseOperationBase(aCursor->mTransaction.clonePtr()), + : TransactionDatabaseOperationBase(aCursor->mTransaction), mCursor(aCursor) #ifdef DEBUG , @@ -8484,13 +8450,12 @@ class Utils final : public PBackgroundIndexedDBUtilsParent { struct DatabaseActorInfo final { friend class mozilla::DefaultDelete; - SafeRefPtr mMetadata; + RefPtr mMetadata; nsTArray> mLiveDatabases; RefPtr mWaitingFactoryOp; - DatabaseActorInfo(SafeRefPtr aMetadata, - Database* aDatabase) - : mMetadata(std::move(aMetadata)) { + DatabaseActorInfo(FullDatabaseMetadata* aMetadata, Database* aDatabase) + : mMetadata(aMetadata) { MOZ_ASSERT(aDatabase); MOZ_COUNT_CTOR(DatabaseActorInfo); @@ -8716,7 +8681,7 @@ class DeleteFilesRunnable final : public Runnable, }; nsCOMPtr mOwningEventTarget; - SafeRefPtr mFileManager; + RefPtr mFileManager; RefPtr mDirectoryLock; nsCOMPtr mDirectory; nsCOMPtr mJournalDirectory; @@ -8724,8 +8689,7 @@ class DeleteFilesRunnable final : public Runnable, State mState; public: - DeleteFilesRunnable(SafeRefPtr aFileManager, - nsTArray&& aFileIds); + DeleteFilesRunnable(FileManager* aFileManager, nsTArray&& aFileIds); void RunImmediately(); @@ -9120,19 +9084,16 @@ class DEBUGThreadSlower final : public nsIThreadObserver { ******************************************************************************/ class MOZ_STACK_CLASS FileHelper final { - const SafeRefPtr mFileManager; + RefPtr mFileManager; - LazyInitializedOnceNotNull> mFileDirectory; - LazyInitializedOnceNotNull> mJournalDirectory; + nsCOMPtr mFileDirectory; + nsCOMPtr mJournalDirectory; class ReadCallback; - LazyInitializedOnceNotNull> mReadCallback; + RefPtr mReadCallback; public: - explicit FileHelper(SafeRefPtr&& aFileManager) - : mFileManager(std::move(aFileManager)) { - MOZ_ASSERT(mFileManager); - } + explicit FileHelper(FileManager* aFileManager) : mFileManager(aFileManager) {} nsresult Init(); @@ -9140,17 +9101,17 @@ class MOZ_STACK_CLASS FileHelper final { MOZ_MUST_USE nsCOMPtr GetJournalFile(const FileInfo& aFileInfo); - nsresult CreateFileFromStream(nsIFile& aFile, nsIFile& aJournalFile, - nsIInputStream& aInputStream, bool aCompress); + nsresult CreateFileFromStream(nsIFile* aFile, nsIFile* aJournalFile, + nsIInputStream* aInputStream, bool aCompress); - nsresult RemoveFile(nsIFile& aFile, nsIFile& aJournalFile); + nsresult RemoveFile(nsIFile* aFile, nsIFile* aJournalFile); private: - nsresult SyncCopy(nsIInputStream& aInputStream, - nsIOutputStream& aOutputStream, char* aBuffer, + nsresult SyncCopy(nsIInputStream* aInputStream, + nsIOutputStream* aOutputStream, char* aBuffer, uint32_t aBufferSize); - nsresult SyncRead(nsIInputStream& aInputStream, char* aBuffer, + nsresult SyncRead(nsIInputStream* aInputStream, char* aBuffer, uint32_t aBufferSize, uint32_t* aRead); }; @@ -9160,37 +9121,37 @@ class MOZ_STACK_CLASS FileHelper final { bool TokenizerIgnoreNothing(char16_t /* aChar */) { return false; } -Result DeserializeStructuredCloneFile( +Result DeserializeStructuredCloneFile( const FileManager& aFileManager, const nsDependentSubstring& aText) { MOZ_ASSERT(!aText.IsEmpty()); - StructuredCloneFileBase::FileType type; + StructuredCloneFile::FileType type; switch (aText.First()) { case char16_t('-'): - type = StructuredCloneFileBase::eMutableFile; + type = StructuredCloneFile::eMutableFile; break; case char16_t('.'): - type = StructuredCloneFileBase::eStructuredClone; + type = StructuredCloneFile::eStructuredClone; break; case char16_t('/'): - type = StructuredCloneFileBase::eWasmBytecode; + type = StructuredCloneFile::eWasmBytecode; break; case char16_t('\\'): - type = StructuredCloneFileBase::eWasmCompiled; + type = StructuredCloneFile::eWasmCompiled; break; default: - type = StructuredCloneFileBase::eBlob; + type = StructuredCloneFile::eBlob; } nsresult rv; int32_t id; - if (type == StructuredCloneFileBase::eBlob) { + if (type == StructuredCloneFile::eBlob) { id = aText.ToInteger(&rv); } else { nsString text(Substring(aText, 1)); @@ -9201,7 +9162,7 @@ Result DeserializeStructuredCloneFile( return Err(rv); } - SafeRefPtr fileInfo = aFileManager.GetFileInfo(id); + RefPtr fileInfo = aFileManager.GetFileInfo(id); MOZ_ASSERT(fileInfo); // XXX In bug 1432133, for some reasons FileInfo object cannot be got. This // is just a short-term fix, and we are working on finding the real cause @@ -9215,18 +9176,17 @@ Result DeserializeStructuredCloneFile( return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); } - return StructuredCloneFileParent{type, std::move(fileInfo)}; + return StructuredCloneFile{type, std::move(fileInfo)}; } -Result, nsresult> -DeserializeStructuredCloneFiles(const FileManager& aFileManager, - const nsAString& aText) { +Result, nsresult> DeserializeStructuredCloneFiles( + const FileManager& aFileManager, const nsAString& aText) { MOZ_ASSERT(!IsOnBackgroundThread()); nsCharSeparatedTokenizerTemplate tokenizer(aText, ' '); - nsTArray result; + nsTArray result; while (tokenizer.hasMoreTokens()) { const auto& token = tokenizer.nextToken(); MOZ_ASSERT(!token.IsEmpty()); @@ -9262,8 +9222,8 @@ bool GetBaseFilename(const nsAString& aFilename, const nsAString& aSuffix, mozilla::Result, nsresult> SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor, - const SafeRefPtr& aDatabase, - const nsTArray& aFiles, + Database* aDatabase, + const nsTArray& aFiles, bool aForPreprocess) { AssertIsOnBackgroundThread(); MOZ_ASSERT(aBackgroundActor); @@ -9275,8 +9235,9 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor, return result; } - nsCOMPtr directory = - aDatabase->GetFileManager().GetCheckedDirectory(); + FileManager* fileManager = aDatabase->GetFileManager(); + + nsCOMPtr directory = fileManager->GetCheckedDirectory(); if (NS_WARN_IF(!directory)) { IDB_REPORT_INTERNAL_ERR(); return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); @@ -9288,9 +9249,9 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor, return Err(NS_ERROR_OUT_OF_MEMORY); } - for (const StructuredCloneFileParent& file : aFiles) { + for (const StructuredCloneFile& file : aFiles) { if (aForPreprocess && - file.Type() != StructuredCloneFileBase::eStructuredClone) { + file.Type() != StructuredCloneFile::eStructuredClone) { continue; } @@ -9306,7 +9267,7 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor, } switch (file.Type()) { - case StructuredCloneFileBase::eBlob: { + case StructuredCloneFile::eBlob: { RefPtr impl = new FileBlobImpl(nativeFile); impl->SetFileId(file.FileInfo().Id()); @@ -9318,18 +9279,18 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor, return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); } - result.EmplaceBack(ipcBlob, StructuredCloneFileBase::eBlob); + result.EmplaceBack(ipcBlob, StructuredCloneFile::eBlob); aDatabase->MapBlob(ipcBlob, file.FileInfoPtr()); break; } - case StructuredCloneFileBase::eMutableFile: { + case StructuredCloneFile::eMutableFile: { if (aDatabase->IsFileHandleDisabled()) { - result.EmplaceBack(null_t(), StructuredCloneFileBase::eMutableFile); + result.EmplaceBack(null_t(), StructuredCloneFile::eMutableFile); } else { - RefPtr actor = MutableFile::Create( - nativeFile, aDatabase.clonePtr(), file.FileInfoPtr()); + RefPtr actor = + MutableFile::Create(nativeFile, aDatabase, file.FileInfoPtr()); if (!actor) { IDB_REPORT_INTERNAL_ERR(); return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); @@ -9345,17 +9306,15 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor, return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); } - result.EmplaceBack(actor.get(), - StructuredCloneFileBase::eMutableFile); + result.EmplaceBack(actor.get(), StructuredCloneFile::eMutableFile); } break; } - case StructuredCloneFileBase::eStructuredClone: { + case StructuredCloneFile::eStructuredClone: { if (!aForPreprocess) { - result.EmplaceBack(null_t(), - StructuredCloneFileBase::eStructuredClone); + result.EmplaceBack(null_t(), StructuredCloneFile::eStructuredClone); } else { RefPtr impl = new FileBlobImpl(nativeFile); impl->SetFileId(file.FileInfo().Id()); @@ -9369,8 +9328,7 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor, return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); } - result.EmplaceBack(ipcBlob, - StructuredCloneFileBase::eStructuredClone); + result.EmplaceBack(ipcBlob, StructuredCloneFile::eStructuredClone); aDatabase->MapBlob(ipcBlob, file.FileInfoPtr()); } @@ -9378,8 +9336,8 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor, break; } - case StructuredCloneFileBase::eWasmBytecode: - case StructuredCloneFileBase::eWasmCompiled: { + case StructuredCloneFile::eWasmBytecode: + case StructuredCloneFile::eWasmCompiled: { // Set file() to null, support for storing WebAssembly.Modules has been // removed in bug 1469395. Support for de-serialization of // WebAssembly.Modules modules has been removed in bug 1561876. Full @@ -10173,7 +10131,7 @@ struct ValuePopulateResponseHelper { // so we construct a FallibleTArray and swap the elements... auto files = cloneInfo.ReleaseFiles(); - FallibleTArray temp; + FallibleTArray temp; temp.SwapElements(files); aFiles->AppendElement(std::move(temp)); } @@ -10184,7 +10142,8 @@ struct ValuePopulateResponseHelper { } private: - LazyInitializedOnceEarlyDestructible + InitializedOnce mCloneInfo; }; @@ -10251,11 +10210,11 @@ nsresult DispatchAndReturnFileReferences( IndexedDatabaseManager* const mgr = IndexedDatabaseManager::Get(); MOZ_ASSERT(mgr); - const SafeRefPtr fileManager = + const RefPtr fileManager = mgr->GetFileManager(aPersistenceType, aOrigin, aDatabaseName); if (fileManager) { - const SafeRefPtr fileInfo = fileManager->GetFileInfo(aFileId); + const RefPtr fileInfo = fileManager->GetFileInfo(aFileId); if (fileInfo) { fileInfo->GetReferences(aMemRefCnt, aDBRefCnt); @@ -10564,15 +10523,14 @@ class DeserializeUpgradeValueHelper final : public Runnable { void PopulateFileIds(nsAString& aFileIds) { for (uint32_t count = mCloneReadInfo.Files().Length(), index = 0; index < count; index++) { - const StructuredCloneFileParent& file = mCloneReadInfo.Files()[index]; + const StructuredCloneFile& file = mCloneReadInfo.Files()[index]; const int64_t id = file.FileInfo().Id(); if (index) { aFileIds.Append(' '); } - aFileIds.AppendInt(file.Type() == StructuredCloneFileBase::eBlob ? id - : -id); + aFileIds.AppendInt(file.Type() == StructuredCloneFile::eBlob ? id : -id); } } @@ -10726,10 +10684,9 @@ nsresult FileManager::AsyncDeleteFile(int64_t aFileId) { ******************************************************************************/ DatabaseConnection::DatabaseConnection( - nsCOMPtr aStorageConnection, - SafeRefPtr aFileManager) - : mStorageConnection(std::move(aStorageConnection)), - mFileManager(std::move(aFileManager)), + mozIStorageConnection* aStorageConnection, FileManager* aFileManager) + : mStorageConnection(aStorageConnection), + mFileManager(aFileManager), mInReadTransaction(false), mInWriteTransaction(false) #ifdef DEBUG @@ -10738,8 +10695,8 @@ DatabaseConnection::DatabaseConnection( #endif { AssertIsOnConnectionThread(); - MOZ_ASSERT(mStorageConnection); - MOZ_ASSERT(mFileManager); + MOZ_ASSERT(aStorageConnection); + MOZ_ASSERT(aFileManager); } DatabaseConnection::~DatabaseConnection() { @@ -10854,7 +10811,7 @@ nsresult DatabaseConnection::BeginWriteTransaction() { MOZ_ASSERT(mFileManager); RefPtr function = - new UpdateRefcountFunction(this, **mFileManager); + new UpdateRefcountFunction(this, mFileManager->get()); rv = (*mStorageConnection) ->CreateFunction(NS_LITERAL_CSTRING("update_refcount"), @@ -11326,9 +11283,9 @@ void DatabaseConnection::Close() { mCachedStatements.Clear(); MOZ_ALWAYS_SUCCEEDS((*mStorageConnection)->Close()); - mStorageConnection.destroy(); + mStorageConnection.reset(); - mFileManager.destroy(); + mFileManager.reset(); } nsresult DatabaseConnection::DisableQuotaChecks() { @@ -11517,7 +11474,7 @@ nsresult DatabaseConnection::AutoSavepoint::Start( aTransaction.GetMode() == IDBTransaction::Mode::Cleanup || aTransaction.GetMode() == IDBTransaction::Mode::VersionChange); - DatabaseConnection* connection = aTransaction.GetDatabase().GetConnection(); + DatabaseConnection* connection = aTransaction.GetDatabase()->GetConnection(); MOZ_ASSERT(connection); connection->AssertIsOnConnectionThread(); @@ -11566,12 +11523,13 @@ nsresult DatabaseConnection::AutoSavepoint::Commit() { } DatabaseConnection::UpdateRefcountFunction::UpdateRefcountFunction( - DatabaseConnection* const aConnection, FileManager& aFileManager) + DatabaseConnection* const aConnection, FileManager* const aFileManager) : mConnection(aConnection), mFileManager(aFileManager), mInSavepoint(false) { MOZ_ASSERT(aConnection); aConnection->AssertIsOnConnectionThread(); + MOZ_ASSERT(aFileManager); } nsresult DatabaseConnection::UpdateRefcountFunction::WillCommit() { @@ -11722,11 +11680,11 @@ nsresult DatabaseConnection::UpdateRefcountFunction::ProcessValue( return rv; } - auto filesOrErr = DeserializeStructuredCloneFiles(mFileManager, ids); + auto filesOrErr = DeserializeStructuredCloneFiles(*mFileManager, ids); if (NS_WARN_IF(filesOrErr.isErr())) { return filesOrErr.unwrapErr(); } - for (const StructuredCloneFileParent& file : filesOrErr.inspect()) { + for (const StructuredCloneFile& file : filesOrErr.inspect()) { const int64_t id = file.FileInfo().Id(); MOZ_ASSERT(id > 0); @@ -11762,7 +11720,7 @@ nsresult DatabaseConnection::UpdateRefcountFunction::CreateJournals() { AUTO_PROFILER_LABEL( "DatabaseConnection::UpdateRefcountFunction::CreateJournals", DOM); - nsCOMPtr journalDirectory = mFileManager.GetJournalDirectory(); + nsCOMPtr journalDirectory = mFileManager->GetJournalDirectory(); if (NS_WARN_IF(!journalDirectory)) { return NS_ERROR_FAILURE; } @@ -11792,7 +11750,7 @@ nsresult DatabaseConnection::UpdateRefcountFunction::RemoveJournals( AUTO_PROFILER_LABEL( "DatabaseConnection::UpdateRefcountFunction::RemoveJournals", DOM); - nsCOMPtr journalDirectory = mFileManager.GetJournalDirectory(); + nsCOMPtr journalDirectory = mFileManager->GetJournalDirectory(); if (NS_WARN_IF(!journalDirectory)) { return NS_ERROR_FAILURE; } @@ -12078,9 +12036,10 @@ void ConnectionPool::IdleTimerCallback(nsITimer* aTimer, void* aClosure) { } nsresult ConnectionPool::GetOrCreateConnection( - const Database& aDatabase, RefPtr* aConnection) { + const Database* aDatabase, RefPtr* aConnection) { MOZ_ASSERT(!NS_IsMainThread()); MOZ_ASSERT(!IsOnBackgroundThread()); + MOZ_ASSERT(aDatabase); MOZ_ASSERT(aConnection); AUTO_PROFILER_LABEL("ConnectionPool::GetOrCreateConnection", DOM); @@ -12089,7 +12048,7 @@ nsresult ConnectionPool::GetOrCreateConnection( { MutexAutoLock lock(mDatabasesMutex); - dbInfo = mDatabases.Get(aDatabase.Id()); + dbInfo = mDatabases.Get(aDatabase->Id()); } MOZ_ASSERT(dbInfo); @@ -12099,15 +12058,15 @@ nsresult ConnectionPool::GetOrCreateConnection( MOZ_ASSERT(!dbInfo->mDEBUGConnectionThread); nsCOMPtr storageConnection; - nsresult rv = - GetStorageConnection(aDatabase.FilePath(), aDatabase.DirectoryLockId(), - aDatabase.TelemetryId(), &storageConnection); + nsresult rv = GetStorageConnection( + aDatabase->FilePath(), aDatabase->DirectoryLockId(), + aDatabase->TelemetryId(), &storageConnection); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - connection = new DatabaseConnection(storageConnection, - aDatabase.GetFileManagerPtr()); + connection = + new DatabaseConnection(storageConnection, aDatabase->GetFileManager()); rv = connection->Init(); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -12118,7 +12077,7 @@ nsresult ConnectionPool::GetOrCreateConnection( IDB_DEBUG_LOG(("ConnectionPool created connection 0x%p for '%s'", dbInfo->mConnection.get(), - NS_ConvertUTF16toUTF8(aDatabase.FilePath()).get())); + NS_ConvertUTF16toUTF8(aDatabase->FilePath()).get())); #ifdef DEBUG dbInfo->mDEBUGConnectionThread = PR_GetCurrentThread(); @@ -13353,12 +13312,12 @@ bool FullObjectStoreMetadata::HasLiveIndexes() const { }); } -SafeRefPtr FullDatabaseMetadata::Duplicate() const { +RefPtr FullDatabaseMetadata::Duplicate() const { AssertIsOnBackgroundThread(); // FullDatabaseMetadata contains two hash tables of pointers that we need to // duplicate so we can't just use the copy constructor. - auto newMetadata = MakeSafeRefPtr(mCommonMetadata); + auto newMetadata = MakeRefPtr(mCommonMetadata); newMetadata->mDatabaseId = mDatabaseId; newMetadata->mFilePath = mFilePath; @@ -13706,8 +13665,8 @@ Database::Database(RefPtr aFactory, const Maybe& aOptionalContentParentId, const nsACString& aGroup, const nsACString& aOrigin, uint32_t aTelemetryId, - SafeRefPtr aMetadata, - SafeRefPtr aFileManager, + RefPtr aMetadata, + RefPtr aFileManager, RefPtr aDirectoryLock, bool aFileHandleDisabled, bool aChromeWriteAccessAllowed) : mFactory(std::move(aFactory)), @@ -13809,7 +13768,7 @@ nsresult Database::EnsureConnection() { AUTO_PROFILER_LABEL("Database::EnsureConnection", DOM); if (!mConnection || !mConnection->GetStorageConnection()) { - nsresult rv = gConnectionPool->GetOrCreateConnection(*this, &mConnection); + nsresult rv = gConnectionPool->GetOrCreateConnection(this, &mConnection); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -13820,25 +13779,27 @@ nsresult Database::EnsureConnection() { return NS_OK; } -bool Database::RegisterTransaction(TransactionBase& aTransaction) { +bool Database::RegisterTransaction(TransactionBase* aTransaction) { AssertIsOnBackgroundThread(); - MOZ_ASSERT(!mTransactions.GetEntry(&aTransaction)); + MOZ_ASSERT(aTransaction); + MOZ_ASSERT(!mTransactions.GetEntry(aTransaction)); MOZ_ASSERT(mDirectoryLock); MOZ_ASSERT(!mInvalidated); MOZ_ASSERT(!mClosed); - if (NS_WARN_IF(!mTransactions.PutEntry(&aTransaction, fallible))) { + if (NS_WARN_IF(!mTransactions.PutEntry(aTransaction, fallible))) { return false; } return true; } -void Database::UnregisterTransaction(TransactionBase& aTransaction) { +void Database::UnregisterTransaction(TransactionBase* aTransaction) { AssertIsOnBackgroundThread(); - MOZ_ASSERT(mTransactions.GetEntry(&aTransaction)); + MOZ_ASSERT(aTransaction); + MOZ_ASSERT(mTransactions.GetEntry(aTransaction)); - mTransactions.RemoveEntry(&aTransaction); + mTransactions.RemoveEntry(aTransaction); MaybeCloseConnection(); } @@ -13909,8 +13870,7 @@ void Database::SetActorAlive() { AddRef(); } -void Database::MapBlob(const IPCBlob& aIPCBlob, - SafeRefPtr aFileInfo) { +void Database::MapBlob(const IPCBlob& aIPCBlob, RefPtr aFileInfo) { AssertIsOnBackgroundThread(); const IPCBlobStream& stream = aIPCBlob.inputStream(); @@ -13920,10 +13880,9 @@ void Database::MapBlob(const IPCBlob& aIPCBlob, stream.get_PIPCBlobInputStreamParent()); MOZ_ASSERT(!mMappedBlobs.GetWeak(actor->ID())); - mMappedBlobs.Put(actor->ID(), AsRefPtr(std::move(aFileInfo))); + mMappedBlobs.Put(actor->ID(), std::move(aFileInfo)); - RefPtr callback = - new UnmapBlobCallback(SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}); + RefPtr callback = new UnmapBlobCallback(this); actor->SetCallback(callback); } @@ -13967,7 +13926,7 @@ void Database::Stringify(nsACString& aResult) const { aResult.AppendInt(mActorDestroyed); } -SafeRefPtr Database::GetBlob(const IPCBlob& aIPCBlob) { +RefPtr Database::GetBlob(const IPCBlob& aIPCBlob) { AssertIsOnBackgroundThread(); const IPCBlobStream& stream = aIPCBlob.inputStream(); @@ -13988,7 +13947,7 @@ SafeRefPtr Database::GetBlob(const IPCBlob& aIPCBlob) { return nullptr; } - return SafeRefPtr{std::move(fileInfo)}; + return fileInfo; } void Database::UnmapBlob(const nsID& aID) { @@ -14137,18 +14096,20 @@ PBackgroundIDBDatabaseFileParent* Database::AllocPBackgroundIDBDatabaseFileParent(const IPCBlob& aIPCBlob) { AssertIsOnBackgroundThread(); - SafeRefPtr fileInfo = GetBlob(aIPCBlob); + RefPtr blobImpl = IPCBlobUtils::Deserialize(aIPCBlob); + MOZ_ASSERT(blobImpl); + + RefPtr fileInfo = GetBlob(aIPCBlob); RefPtr actor; if (fileInfo) { - actor = new DatabaseFile(std::move(fileInfo)); + actor = new DatabaseFile(fileInfo); } else { // This is a blob we haven't seen before. fileInfo = mFileManager->CreateFileInfo(); MOZ_ASSERT(fileInfo); - actor = new DatabaseFile(IPCBlobUtils::Deserialize(aIPCBlob), - std::move(fileInfo)); + actor = new DatabaseFile(blobImpl, fileInfo); } MOZ_ASSERT(actor); @@ -14192,8 +14153,7 @@ Database::AllocPBackgroundIDBDatabaseRequestParent( switch (aParams.type()) { case DatabaseRequestParams::TCreateFileParams: { - actor = new CreateFileOp(SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - aParams); + actor = new CreateFileOp(this, aParams); NotePendingCreateFileOp(); break; @@ -14310,8 +14270,7 @@ PBackgroundIDBTransactionParent* Database::AllocPBackgroundIDBTransactionParent( infallibleObjectStores.SwapElements(fallibleObjectStores); RefPtr transaction = - new NormalTransaction(SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - aMode, infallibleObjectStores); + new NormalTransaction(this, aMode, infallibleObjectStores); MOZ_ASSERT(infallibleObjectStores.IsEmpty()); @@ -14342,8 +14301,7 @@ mozilla::ipc::IPCResult Database::RecvPBackgroundIDBTransactionConstructor( auto* transaction = static_cast(aActor); - RefPtr startOp = new StartTransactionOp( - SafeRefPtr{transaction, AcquireStrongRefFromRawPtr{}}); + RefPtr startOp = new StartTransactionOp(transaction); uint64_t transactionId = startOp->StartOnConnectionPool( GetLoggingInfo()->Id(), mMetadata->mDatabaseId, @@ -14352,7 +14310,7 @@ mozilla::ipc::IPCResult Database::RecvPBackgroundIDBTransactionConstructor( transaction->Init(transactionId); - if (NS_WARN_IF(!RegisterTransaction(*transaction))) { + if (NS_WARN_IF(!RegisterTransaction(transaction))) { IDB_REPORT_INTERNAL_ERR(); transaction->Abort(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR, /* aForce */ false); return IPC_OK(); @@ -14512,17 +14470,17 @@ void Database::StartTransactionOp::Cleanup() { * TransactionBase ******************************************************************************/ -TransactionBase::TransactionBase(SafeRefPtr aDatabase, Mode aMode) - : mDatabase(std::move(aDatabase)), - mDatabaseId(mDatabase->Id()), +TransactionBase::TransactionBase(Database* aDatabase, Mode aMode) + : mDatabase(aDatabase), + mDatabaseId(aDatabase->Id()), mLoggingSerialNumber( - mDatabase->GetLoggingInfo()->NextTransactionSN(aMode)), + aDatabase->GetLoggingInfo()->NextTransactionSN(aMode)), mActiveRequestCount(0), mInvalidatedOnAnyThread(false), mMode(aMode), mResultCode(NS_OK) { AssertIsOnBackgroundThread(); - MOZ_ASSERT(mDatabase); + MOZ_ASSERT(aDatabase); MOZ_ASSERT(mLoggingSerialNumber); } @@ -14607,9 +14565,7 @@ void TransactionBase::CommitOrAbort() { mResultCode = NS_ERROR_DOM_INDEXEDDB_ABORT_ERR; } - RefPtr commitOp = - new CommitOp(SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - ClampResultCode(mResultCode)); + RefPtr commitOp = new CommitOp(this, ClampResultCode(mResultCode)); gConnectionPool->Finish(TransactionId(), commitOp); } @@ -14624,8 +14580,8 @@ RefPtr TransactionBase::GetMetadataForObjectStoreId( } RefPtr metadata; - if (!mDatabase->Metadata().mObjectStores.Get(aObjectStoreId, - getter_AddRefs(metadata)) || + if (!mDatabase->Metadata()->mObjectStores.Get(aObjectStoreId, + getter_AddRefs(metadata)) || metadata->mDeleted) { return nullptr; } @@ -15035,7 +14991,7 @@ bool TransactionBase::VerifyRequestParams( MOZ_ASSERT(file.type() != DatabaseOrMutableFile::T__None); switch (fileAddInfo.type()) { - case StructuredCloneFileBase::eBlob: + case StructuredCloneFile::eBlob: if (NS_WARN_IF( file.type() != DatabaseOrMutableFile::TPBackgroundIDBDatabaseFileParent)) { @@ -15048,7 +15004,7 @@ bool TransactionBase::VerifyRequestParams( } break; - case StructuredCloneFileBase::eMutableFile: { + case StructuredCloneFile::eMutableFile: { if (NS_WARN_IF(file.type() != DatabaseOrMutableFile::TPBackgroundMutableFileParent)) { ASSERT_UNLESS_FUZZING(); @@ -15077,10 +15033,10 @@ bool TransactionBase::VerifyRequestParams( break; } - case StructuredCloneFileBase::eStructuredClone: - case StructuredCloneFileBase::eWasmBytecode: - case StructuredCloneFileBase::eWasmCompiled: - case StructuredCloneFileBase::eEndGuard: + case StructuredCloneFile::eStructuredClone: + case StructuredCloneFile::eWasmBytecode: + case StructuredCloneFile::eWasmCompiled: + case StructuredCloneFile::eEndGuard: ASSERT_UNLESS_FUZZING(); return false; @@ -15164,79 +15120,59 @@ PBackgroundIDBRequestParent* TransactionBase::AllocRequest( switch (aParams.type()) { case RequestParams::TObjectStoreAddParams: case RequestParams::TObjectStorePutParams: - actor = new ObjectStoreAddOrPutRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, std::move(aParams)); + actor = new ObjectStoreAddOrPutRequestOp(this, std::move(aParams)); break; case RequestParams::TObjectStoreGetParams: - actor = new ObjectStoreGetRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aParams, - /* aGetAll */ false); + actor = new ObjectStoreGetRequestOp(this, aParams, /* aGetAll */ false); break; case RequestParams::TObjectStoreGetAllParams: - actor = new ObjectStoreGetRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aParams, - /* aGetAll */ true); + actor = new ObjectStoreGetRequestOp(this, aParams, /* aGetAll */ true); break; case RequestParams::TObjectStoreGetKeyParams: - actor = new ObjectStoreGetKeyRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aParams, - /* aGetAll */ false); + actor = + new ObjectStoreGetKeyRequestOp(this, aParams, /* aGetAll */ false); break; case RequestParams::TObjectStoreGetAllKeysParams: - actor = new ObjectStoreGetKeyRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aParams, - /* aGetAll */ true); + actor = new ObjectStoreGetKeyRequestOp(this, aParams, /* aGetAll */ true); break; case RequestParams::TObjectStoreDeleteParams: actor = new ObjectStoreDeleteRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - aParams.get_ObjectStoreDeleteParams()); + this, aParams.get_ObjectStoreDeleteParams()); break; case RequestParams::TObjectStoreClearParams: actor = new ObjectStoreClearRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - aParams.get_ObjectStoreClearParams()); + this, aParams.get_ObjectStoreClearParams()); break; case RequestParams::TObjectStoreCountParams: actor = new ObjectStoreCountRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - aParams.get_ObjectStoreCountParams()); + this, aParams.get_ObjectStoreCountParams()); break; case RequestParams::TIndexGetParams: - actor = - new IndexGetRequestOp(SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - aParams, /* aGetAll */ false); + actor = new IndexGetRequestOp(this, aParams, /* aGetAll */ false); break; case RequestParams::TIndexGetKeyParams: - actor = new IndexGetKeyRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aParams, - /* aGetAll */ false); + actor = new IndexGetKeyRequestOp(this, aParams, /* aGetAll */ false); break; case RequestParams::TIndexGetAllParams: - actor = - new IndexGetRequestOp(SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - aParams, /* aGetAll */ true); + actor = new IndexGetRequestOp(this, aParams, /* aGetAll */ true); break; case RequestParams::TIndexGetAllKeysParams: - actor = new IndexGetKeyRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aParams, - /* aGetAll */ true); + actor = new IndexGetKeyRequestOp(this, aParams, /* aGetAll */ true); break; case RequestParams::TIndexCountParams: - actor = new IndexCountRequestOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aParams); + actor = new IndexCountRequestOp(this, aParams); break; default: @@ -15255,7 +15191,7 @@ bool TransactionBase::StartRequest(PBackgroundIDBRequestParent* aActor) { auto* op = static_cast(aActor); - if (NS_WARN_IF(!op->Init(*this))) { + if (NS_WARN_IF(!op->Init(this))) { op->Cleanup(); return false; } @@ -15327,27 +15263,23 @@ PBackgroundIDBCursorParent* TransactionBase::AllocCursor( case OpenCursorParams::TObjectStoreOpenCursorParams: MOZ_ASSERT(!indexMetadata); return MakeAndAddRef>( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - std::move(objectStoreMetadata), direction, + this, std::move(objectStoreMetadata), direction, CursorBase::ConstructFromTransactionBase{}) .take(); case OpenCursorParams::TObjectStoreOpenKeyCursorParams: MOZ_ASSERT(!indexMetadata); return MakeAndAddRef>( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - std::move(objectStoreMetadata), direction, + this, std::move(objectStoreMetadata), direction, CursorBase::ConstructFromTransactionBase{}) .take(); case OpenCursorParams::TIndexOpenCursorParams: return MakeAndAddRef>( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - std::move(objectStoreMetadata), std::move(indexMetadata), + this, std::move(objectStoreMetadata), std::move(indexMetadata), direction, CursorBase::ConstructFromTransactionBase{}) .take(); case OpenCursorParams::TIndexOpenKeyCursorParams: return MakeAndAddRef>( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - std::move(objectStoreMetadata), std::move(indexMetadata), + this, std::move(objectStoreMetadata), std::move(indexMetadata), direction, CursorBase::ConstructFromTransactionBase{}) .take(); default: @@ -15385,9 +15317,9 @@ bool TransactionBase::DeallocCursor(PBackgroundIDBCursorParent* const aActor) { ******************************************************************************/ NormalTransaction::NormalTransaction( - SafeRefPtr aDatabase, TransactionBase::Mode aMode, + Database* aDatabase, TransactionBase::Mode aMode, nsTArray>& aObjectStores) - : TransactionBase(std::move(aDatabase), aMode) { + : TransactionBase(aDatabase, aMode) { AssertIsOnBackgroundThread(); MOZ_ASSERT(!aObjectStores.IsEmpty()); @@ -15522,7 +15454,7 @@ bool NormalTransaction::DeallocPBackgroundIDBCursorParent( VersionChangeTransaction::VersionChangeTransaction( OpenDatabaseOp* aOpenDatabaseOp) - : TransactionBase(aOpenDatabaseOp->mDatabase.clonePtr(), + : TransactionBase(aOpenDatabaseOp->mDatabase, IDBTransaction::Mode::VersionChange), mOpenDatabaseOp(aOpenDatabaseOp) { AssertIsOnBackgroundThread(); @@ -15561,25 +15493,27 @@ bool VersionChangeTransaction::CopyDatabaseMetadata() { AssertIsOnBackgroundThread(); MOZ_ASSERT(!mOldMetadata); - const auto& origMetadata = GetDatabase().Metadata(); + const RefPtr origMetadata = GetDatabase()->Metadata(); + MOZ_ASSERT(origMetadata); - SafeRefPtr newMetadata = origMetadata.Duplicate(); + RefPtr newMetadata = origMetadata->Duplicate(); if (NS_WARN_IF(!newMetadata)) { return false; } // Replace the live metadata with the new mutable copy. DatabaseActorInfo* info; - MOZ_ALWAYS_TRUE(gLiveDatabaseHashtable->Get(origMetadata.mDatabaseId, &info)); + MOZ_ALWAYS_TRUE( + gLiveDatabaseHashtable->Get(origMetadata->mDatabaseId, &info)); MOZ_ASSERT(!info->mLiveDatabases.IsEmpty()); - MOZ_ASSERT(info->mMetadata == &origMetadata); + MOZ_ASSERT(info->mMetadata == origMetadata); mOldMetadata = std::move(info->mMetadata); info->mMetadata = std::move(newMetadata); // Replace metadata pointers for all live databases. for (const auto& liveDatabase : info->mLiveDatabases) { - liveDatabase->mMetadata = info->mMetadata.clonePtr(); + liveDatabase->mMetadata = info->mMetadata; } return true; @@ -15587,6 +15521,7 @@ bool VersionChangeTransaction::CopyDatabaseMetadata() { void VersionChangeTransaction::UpdateMetadata(nsresult aResult) { AssertIsOnBackgroundThread(); + MOZ_ASSERT(GetDatabase()); MOZ_ASSERT(mOpenDatabaseOp); MOZ_ASSERT(!!mActorWasAlive == !!mOpenDatabaseOp->mDatabase); MOZ_ASSERT_IF(mActorWasAlive, !mOpenDatabaseOp->mDatabaseId.IsEmpty()); @@ -15595,7 +15530,7 @@ void VersionChangeTransaction::UpdateMetadata(nsresult aResult) { return; } - SafeRefPtr oldMetadata = std::move(mOldMetadata); + RefPtr oldMetadata = std::move(mOldMetadata); DatabaseActorInfo* info; if (!gLiveDatabaseHashtable->Get(oldMetadata->mDatabaseId, &info)) { @@ -15633,7 +15568,7 @@ void VersionChangeTransaction::UpdateMetadata(nsresult aResult) { info->mMetadata = std::move(oldMetadata); for (auto& liveDatabase : info->mLiveDatabases) { - liveDatabase->mMetadata = info->mMetadata.clonePtr(); + liveDatabase->mMetadata = info->mMetadata; } } } @@ -15725,8 +15660,8 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvCreateObjectStore( return IPC_FAIL_NO_REASON(this); } - const SafeRefPtr dbMetadata = - GetDatabase().MetadataPtr(); + const RefPtr dbMetadata = GetDatabase()->Metadata(); + MOZ_ASSERT(dbMetadata); if (NS_WARN_IF(aMetadata.id() != dbMetadata->mNextObjectStoreId)) { ASSERT_UNLESS_FUZZING(); @@ -15758,10 +15693,9 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvCreateObjectStore( dbMetadata->mNextObjectStoreId++; - RefPtr op = new CreateObjectStoreOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aMetadata); + RefPtr op = new CreateObjectStoreOp(this, aMetadata); - if (NS_WARN_IF(!op->Init(*this))) { + if (NS_WARN_IF(!op->Init(this))) { op->Cleanup(); return IPC_FAIL_NO_REASON(this); } @@ -15780,10 +15714,11 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvDeleteObjectStore( return IPC_FAIL_NO_REASON(this); } - const auto& dbMetadata = GetDatabase().Metadata(); - MOZ_ASSERT(dbMetadata.mNextObjectStoreId > 0); + const RefPtr dbMetadata = GetDatabase()->Metadata(); + MOZ_ASSERT(dbMetadata); + MOZ_ASSERT(dbMetadata->mNextObjectStoreId > 0); - if (NS_WARN_IF(aObjectStoreId >= dbMetadata.mNextObjectStoreId)) { + if (NS_WARN_IF(aObjectStoreId >= dbMetadata->mNextObjectStoreId)) { ASSERT_UNLESS_FUZZING(); return IPC_FAIL_NO_REASON(this); } @@ -15805,7 +15740,7 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvDeleteObjectStore( DebugOnly foundTargetId = false; const bool isLastObjectStore = std::all_of( - dbMetadata.mObjectStores.begin(), dbMetadata.mObjectStores.end(), + dbMetadata->mObjectStores.begin(), dbMetadata->mObjectStores.end(), [&foundTargetId, aObjectStoreId](const auto& objectStoreEntry) -> bool { if (uint64_t(aObjectStoreId) == objectStoreEntry.GetKey()) { foundTargetId = true; @@ -15817,10 +15752,9 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvDeleteObjectStore( MOZ_ASSERT_IF(isLastObjectStore, foundTargetId); RefPtr op = - new DeleteObjectStoreOp(SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - foundMetadata, isLastObjectStore); + new DeleteObjectStoreOp(this, foundMetadata, isLastObjectStore); - if (NS_WARN_IF(!op->Init(*this))) { + if (NS_WARN_IF(!op->Init(this))) { op->Cleanup(); return IPC_FAIL_NO_REASON(this); } @@ -15839,14 +15773,13 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvRenameObjectStore( return IPC_FAIL_NO_REASON(this); } - { - const auto& dbMetadata = GetDatabase().Metadata(); - MOZ_ASSERT(dbMetadata.mNextObjectStoreId > 0); + const RefPtr dbMetadata = GetDatabase()->Metadata(); + MOZ_ASSERT(dbMetadata); + MOZ_ASSERT(dbMetadata->mNextObjectStoreId > 0); - if (NS_WARN_IF(aObjectStoreId >= dbMetadata.mNextObjectStoreId)) { - ASSERT_UNLESS_FUZZING(); - return IPC_FAIL_NO_REASON(this); - } + if (NS_WARN_IF(aObjectStoreId >= dbMetadata->mNextObjectStoreId)) { + ASSERT_UNLESS_FUZZING(); + return IPC_FAIL_NO_REASON(this); } RefPtr foundMetadata = @@ -15864,10 +15797,10 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvRenameObjectStore( foundMetadata->mCommonMetadata.name() = aName; - RefPtr renameOp = new RenameObjectStoreOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, foundMetadata); + RefPtr renameOp = + new RenameObjectStoreOp(this, foundMetadata); - if (NS_WARN_IF(!renameOp->Init(*this))) { + if (NS_WARN_IF(!renameOp->Init(this))) { renameOp->Cleanup(); return IPC_FAIL_NO_REASON(this); } @@ -15892,7 +15825,8 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvCreateIndex( return IPC_FAIL_NO_REASON(this); } - const auto dbMetadata = GetDatabase().MetadataPtr(); + const RefPtr dbMetadata = GetDatabase()->Metadata(); + MOZ_ASSERT(dbMetadata); if (NS_WARN_IF(aMetadata.id() != dbMetadata->mNextIndexId)) { ASSERT_UNLESS_FUZZING(); @@ -15931,11 +15865,9 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvCreateIndex( dbMetadata->mNextIndexId++; - RefPtr op = - new CreateIndexOp(SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - aObjectStoreId, aMetadata); + RefPtr op = new CreateIndexOp(this, aObjectStoreId, aMetadata); - if (NS_WARN_IF(!op->Init(*this))) { + if (NS_WARN_IF(!op->Init(this))) { op->Cleanup(); return IPC_FAIL_NO_REASON(this); } @@ -15959,20 +15891,20 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvDeleteIndex( ASSERT_UNLESS_FUZZING(); return IPC_FAIL_NO_REASON(this); } - { - const auto& dbMetadata = GetDatabase().Metadata(); - MOZ_ASSERT(dbMetadata.mNextObjectStoreId > 0); - MOZ_ASSERT(dbMetadata.mNextIndexId > 0); - if (NS_WARN_IF(aObjectStoreId >= dbMetadata.mNextObjectStoreId)) { - ASSERT_UNLESS_FUZZING(); - return IPC_FAIL_NO_REASON(this); - } + const RefPtr dbMetadata = GetDatabase()->Metadata(); + MOZ_ASSERT(dbMetadata); + MOZ_ASSERT(dbMetadata->mNextObjectStoreId > 0); + MOZ_ASSERT(dbMetadata->mNextIndexId > 0); - if (NS_WARN_IF(aIndexId >= dbMetadata.mNextIndexId)) { - ASSERT_UNLESS_FUZZING(); - return IPC_FAIL_NO_REASON(this); - } + if (NS_WARN_IF(aObjectStoreId >= dbMetadata->mNextObjectStoreId)) { + ASSERT_UNLESS_FUZZING(); + return IPC_FAIL_NO_REASON(this); + } + + if (NS_WARN_IF(aIndexId >= dbMetadata->mNextIndexId)) { + ASSERT_UNLESS_FUZZING(); + return IPC_FAIL_NO_REASON(this); } RefPtr foundObjectStoreMetadata = @@ -16013,10 +15945,10 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvDeleteIndex( MOZ_ASSERT_IF(isLastIndex, foundTargetId); RefPtr op = new DeleteIndexOp( - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aObjectStoreId, aIndexId, + this, aObjectStoreId, aIndexId, foundIndexMetadata->mCommonMetadata.unique(), isLastIndex); - if (NS_WARN_IF(!op->Init(*this))) { + if (NS_WARN_IF(!op->Init(this))) { op->Cleanup(); return IPC_FAIL_NO_REASON(this); } @@ -16041,8 +15973,7 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvRenameIndex( return IPC_FAIL_NO_REASON(this); } - const SafeRefPtr dbMetadata = - GetDatabase().MetadataPtr(); + const RefPtr dbMetadata = GetDatabase()->Metadata(); MOZ_ASSERT(dbMetadata); MOZ_ASSERT(dbMetadata->mNextObjectStoreId > 0); MOZ_ASSERT(dbMetadata->mNextIndexId > 0); @@ -16081,10 +16012,9 @@ mozilla::ipc::IPCResult VersionChangeTransaction::RecvRenameIndex( foundIndexMetadata->mCommonMetadata.name() = aName; RefPtr renameOp = - new RenameIndexOp(SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, - foundIndexMetadata, aObjectStoreId); + new RenameIndexOp(this, foundIndexMetadata, aObjectStoreId); - if (NS_WARN_IF(!renameOp->Init(*this))) { + if (NS_WARN_IF(!renameOp->Init(this))) { renameOp->Cleanup(); return IPC_FAIL_NO_REASON(this); } @@ -16158,7 +16088,7 @@ bool VersionChangeTransaction::DeallocPBackgroundIDBCursorParent( * CursorBase ******************************************************************************/ -CursorBase::CursorBase(SafeRefPtr aTransaction, +CursorBase::CursorBase(RefPtr aTransaction, RefPtr aObjectStoreMetadata, const Direction aDirection, const ConstructFromTransactionBase /*aConstructionTag*/) @@ -16318,7 +16248,7 @@ bool Cursor::Start(const OpenCursorParams& aParams) { const RefPtr openOp = new OpenOp(this, optionalKeyRange); - if (NS_WARN_IF(!openOp->Init(*mTransaction))) { + if (NS_WARN_IF(!openOp->Init(mTransaction))) { openOp->Cleanup(); return false; } @@ -16420,11 +16350,11 @@ void Cursor::ActorDestroy(ActorDestroyReason aWhy) { } if constexpr (IsValueCursor) { - this->mBackgroundParent.destroy(); + this->mBackgroundParent.reset(); } - this->mObjectStoreMetadata.destroy(); + this->mObjectStoreMetadata.reset(); if constexpr (IsIndexCursor) { - this->mIndexMetadata.destroy(); + this->mIndexMetadata.reset(); } } @@ -16508,7 +16438,7 @@ mozilla::ipc::IPCResult Cursor::RecvContinue( const RefPtr continueOp = new ContinueOp(this, aParams, positionOrError.unwrap()); - if (NS_WARN_IF(!continueOp->Init(*mTransaction))) { + if (NS_WARN_IF(!continueOp->Init(mTransaction))) { continueOp->Cleanup(); return IPC_FAIL_NO_REASON(this); } @@ -16635,10 +16565,8 @@ nsresult FileManager::Init(nsIFile* aDirectory, // 0, but the dbRefCnt is non-zero, which will keep the FileInfo object // alive. MOZ_ASSERT(dbRefCnt > 0); - mFileInfos.Put( - id, new FileInfo(FileManagerGuard{}, - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, id, - static_cast(dbRefCnt))); + mFileInfos.Put(id, new FileInfo(FileManagerGuard{}, this, id, + static_cast(dbRefCnt))); mLastFileId = std::max(id, mLastFileId); } @@ -17525,13 +17453,12 @@ void QuotaClient::InvalidateLiveDatabasesMatching(const Condition& aCondition) { // we need to make a temporary list of the databases to invalidate to avoid // iterator invalidation. - nsTArray> databases; + nsTArray> databases; for (const auto& liveDatabasesEntry : *gLiveDatabaseHashtable) { for (Database* database : liveDatabasesEntry.GetData()->mLiveDatabases) { if (aCondition(database)) { - databases.AppendElement( - SafeRefPtr{database, AcquireStrongRefFromRawPtr{}}); + databases.AppendElement(database); } } } @@ -17717,8 +17644,8 @@ void QuotaClient::DeleteTimerCallback(nsITimer* aTimer, void* aClosure) { const auto& value = pendingDeleteInfoEntry.GetData(); MOZ_ASSERT(!value->IsEmpty()); - RefPtr runnable = new DeleteFilesRunnable( - SafeRefPtr{key, AcquireStrongRefFromRawPtr{}}, std::move(*value)); + RefPtr runnable = + new DeleteFilesRunnable(key, std::move(*value)); MOZ_ASSERT(value->IsEmpty()); @@ -17964,11 +17891,11 @@ void QuotaClient::ProcessMaintenanceQueue() { * DeleteFilesRunnable ******************************************************************************/ -DeleteFilesRunnable::DeleteFilesRunnable(SafeRefPtr aFileManager, +DeleteFilesRunnable::DeleteFilesRunnable(FileManager* aFileManager, nsTArray&& aFileIds) : Runnable("dom::indexeddb::DeleteFilesRunnable"), mOwningEventTarget(GetCurrentThreadEventTarget()), - mFileManager(std::move(aFileManager)), + mFileManager(aFileManager), mFileIds(std::move(aFileIds)), mState(State_Initial) {} @@ -19397,8 +19324,8 @@ nsresult UpgradeFileIdsFunction::Init(nsIFile* aFMDirectory, // This file manager doesn't need real origin info, etc. The only purpose is // to store file ids without adding more complexity or code duplication. auto fileManager = - MakeSafeRefPtr(PERSISTENCE_TYPE_INVALID, EmptyCString(), - EmptyCString(), EmptyString(), false); + MakeRefPtr(PERSISTENCE_TYPE_INVALID, EmptyCString(), + EmptyCString(), EmptyString(), false); nsresult rv = fileManager->Init(aFMDirectory, aConnection); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -19604,7 +19531,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob( return Err(NS_ERROR_OUT_OF_MEMORY); } - nsTArray files; + nsTArray files; if (!aFileIds.IsVoid()) { auto filesOrErr = DeserializeStructuredCloneFiles(aFileManager, aFileIds); if (NS_WARN_IF(filesOrErr.isErr())) { @@ -19630,7 +19557,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob( nsresult rv; - nsTArray files; + nsTArray files; if (!aFileIds.IsVoid()) { auto filesOrErr = DeserializeStructuredCloneFiles(aFileManager, aFileIds); if (NS_WARN_IF(filesOrErr.isErr())) { @@ -19656,8 +19583,8 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob( } // XXX Why can there be multiple files, but we use only a single one here? - const StructuredCloneFileParent& file = files[index]; - MOZ_ASSERT(file.Type() == StructuredCloneFileBase::eStructuredClone); + const StructuredCloneFile& file = files[index]; + MOZ_ASSERT(file.Type() == StructuredCloneFile::eStructuredClone); const nsCOMPtr nativeFile = file.FileInfo().GetFileForFileInfo(); if (NS_WARN_IF(!nativeFile)) { @@ -19796,14 +19723,15 @@ void CommonOpenOpHelperBase::AppendConditionClause( // static nsresult DatabaseOperationBase::GetUniqueIndexTableForObjectStore( - TransactionBase& aTransaction, const IndexOrObjectStoreId aObjectStoreId, + TransactionBase* aTransaction, const IndexOrObjectStoreId aObjectStoreId, Maybe& aMaybeUniqueIndexTable) { AssertIsOnBackgroundThread(); + MOZ_ASSERT(aTransaction); MOZ_ASSERT(aObjectStoreId); MOZ_ASSERT(aMaybeUniqueIndexTable.isNothing()); const RefPtr objectStoreMetadata = - aTransaction.GetMetadataForObjectStoreId(aObjectStoreId); + aTransaction->GetMetadataForObjectStoreId(aObjectStoreId); MOZ_ASSERT(objectStoreMetadata); if (!objectStoreMetadata->mIndexes.Count()) { @@ -20377,8 +20305,8 @@ void DatabaseOperationBase::AutoSetProgressHandler::Unregister() { mConnection = nullptr; } -MutableFile::MutableFile(nsIFile* aFile, SafeRefPtr aDatabase, - SafeRefPtr aFileInfo) +MutableFile::MutableFile(nsIFile* aFile, RefPtr aDatabase, + RefPtr aFileInfo) : BackgroundMutableFileParentBase(FILE_HANDLE_STORAGE_IDB, aDatabase->Id(), IntString(aFileInfo->Id()), aFile), mDatabase(std::move(aDatabase)), @@ -20390,13 +20318,12 @@ MutableFile::MutableFile(nsIFile* aFile, SafeRefPtr aDatabase, MutableFile::~MutableFile() { mDatabase->UnregisterMutableFile(this); } -RefPtr MutableFile::Create(nsIFile* aFile, - SafeRefPtr aDatabase, - SafeRefPtr aFileInfo) { +RefPtr MutableFile::Create(nsIFile* aFile, Database* aDatabase, + RefPtr aFileInfo) { AssertIsOnBackgroundThread(); RefPtr newMutableFile = - new MutableFile(aFile, aDatabase.clonePtr(), std::move(aFileInfo)); + new MutableFile(aFile, aDatabase, std::move(aFileInfo)); if (!aDatabase->RegisterMutableFile(newMutableFile)) { return nullptr; @@ -21003,7 +20930,7 @@ nsresult FactoryOp::CheckPermission( } nsresult FactoryOp::SendVersionChangeMessages( - DatabaseActorInfo* aDatabaseActorInfo, Maybe aOpeningDatabase, + DatabaseActorInfo* aDatabaseActorInfo, Database* aOpeningDatabase, uint64_t aOldVersion, const Maybe& aNewVersion) { AssertIsOnOwningThread(); MOZ_ASSERT(aDatabaseActorInfo); @@ -21016,12 +20943,10 @@ nsresult FactoryOp::SendVersionChangeMessages( if (liveCount > expectedCount) { FallibleTArray maybeBlockedDatabases; for (const auto& database : aDatabaseActorInfo->mLiveDatabases) { - if ((!aOpeningDatabase || database.get() != &aOpeningDatabase.ref()) && + if ((!aOpeningDatabase || database != aOpeningDatabase) && !database->IsClosed() && - NS_WARN_IF(!maybeBlockedDatabases.AppendElement( - SafeRefPtr{static_cast(database), - AcquireStrongRefFromRawPtr{}}, - fallible))) { + NS_WARN_IF( + !maybeBlockedDatabases.AppendElement(database, fallible))) { return NS_ERROR_OUT_OF_MEMORY; } } @@ -21337,7 +21262,7 @@ OpenDatabaseOp::OpenDatabaseOp(RefPtr aFactory, const CommonFactoryRequestParams& aParams) : FactoryOp(std::move(aFactory), std::move(aContentParent), aParams, /* aDeleting */ false), - mMetadata(MakeRefPtr(aParams.metadata())), + mMetadata(new FullDatabaseMetadata(aParams.metadata())), mRequestedVersion(aParams.metadata().version()), mVersionChangeOp(nullptr), mTelemetryId(0) { @@ -21530,18 +21455,18 @@ nsresult OpenDatabaseOp::DoDatabaseWork() { IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get(); MOZ_ASSERT(mgr); - SafeRefPtr fileManager = + RefPtr fileManager = mgr->GetFileManager(persistenceType, mOrigin, databaseName); if (!fileManager) { - fileManager = MakeSafeRefPtr(persistenceType, mGroup, mOrigin, - databaseName, mEnforcingQuota); + fileManager = new FileManager(persistenceType, mGroup, mOrigin, + databaseName, mEnforcingQuota); rv = fileManager->Init(fmDirectory, connection); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - mgr->AddFileManager(fileManager.clonePtr()); + mgr->AddFileManager(fileManager); } mFileManager = std::move(fileManager); @@ -22040,24 +21965,24 @@ nsresult OpenDatabaseOp::BeginVersionChange() { DatabaseActorInfo* info; MOZ_ALWAYS_TRUE(gLiveDatabaseHashtable->Get(mDatabaseId, &info)); - MOZ_ASSERT(info->mLiveDatabases.Contains(mDatabase.unsafeGetRawPtr())); + MOZ_ASSERT(info->mLiveDatabases.Contains(mDatabase)); MOZ_ASSERT(!info->mWaitingFactoryOp); MOZ_ASSERT(info->mMetadata == mMetadata); - auto transaction = MakeSafeRefPtr(this); + RefPtr transaction = + new VersionChangeTransaction(this); if (NS_WARN_IF(!transaction->CopyDatabaseMetadata())) { return NS_ERROR_OUT_OF_MEMORY; } MOZ_ASSERT(info->mMetadata != mMetadata); - mMetadata = info->mMetadata.clonePtr(); + mMetadata = info->mMetadata; Maybe newVersion = Some(mRequestedVersion); - nsresult rv = SendVersionChangeMessages(info, mDatabase.maybeDeref(), - mMetadata->mCommonMetadata.version(), - newVersion); + nsresult rv = SendVersionChangeMessages( + info, mDatabase, mMetadata->mCommonMetadata.version(), newVersion); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -22087,7 +22012,7 @@ void OpenDatabaseOp::NoteDatabaseClosed(Database* aDatabase) { if (mState != State::WaitingForOtherDatabasesToClose) { MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty()); MOZ_ASSERT( - mRequestedVersion > aDatabase->Metadata().mCommonMetadata.version(), + mRequestedVersion > aDatabase->Metadata()->mCommonMetadata.version(), "Must only be closing databases for a previous version!"); return; } @@ -22166,7 +22091,7 @@ nsresult OpenDatabaseOp::DispatchToWorkThread() { const nsID& backgroundChildLoggingId = mVersionChangeTransaction->GetLoggingInfo()->Id(); - if (NS_WARN_IF(!mDatabase->RegisterTransaction(*mVersionChangeTransaction))) { + if (NS_WARN_IF(!mDatabase->RegisterTransaction(mVersionChangeTransaction))) { return NS_ERROR_OUT_OF_MEMORY; } @@ -22203,7 +22128,7 @@ nsresult OpenDatabaseOp::SendUpgradeNeeded() { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } - const SafeRefPtr transaction = + const RefPtr transaction = std::move(mVersionChangeTransaction); nsresult rv = EnsureDatabaseActorIsAlive(); @@ -22215,9 +22140,8 @@ nsresult OpenDatabaseOp::SendUpgradeNeeded() { transaction->SetActorAlive(); if (!mDatabase->SendPBackgroundIDBVersionChangeTransactionConstructor( - transaction.unsafeGetRawPtr(), mMetadata->mCommonMetadata.version(), - mRequestedVersion, mMetadata->mNextObjectStoreId, - mMetadata->mNextIndexId)) { + transaction, mMetadata->mCommonMetadata.version(), mRequestedVersion, + mMetadata->mNextObjectStoreId, mMetadata->mNextIndexId)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } @@ -22266,11 +22190,9 @@ void OpenDatabaseOp::SendResults() { if (NS_SUCCEEDED(rv)) { // We successfully opened a database so use its actor as the success // result for this request. - - // XXX OpenDatabaseRequestResponse stores a raw pointer, can this be - // avoided? - response = - OpenDatabaseRequestResponse{mDatabase.unsafeGetRawPtr(), nullptr}; + OpenDatabaseRequestResponse openResponse; + openResponse.databaseParent() = mDatabase; + response = openResponse; } else { response = ClampResultCode(rv); #ifdef DEBUG @@ -22349,21 +22271,20 @@ void OpenDatabaseOp::EnsureDatabaseActor() { DatabaseActorInfo* info; if (gLiveDatabaseHashtable->Get(mDatabaseId, &info)) { - AssertMetadataConsistency(*info->mMetadata); - mMetadata = info->mMetadata.clonePtr(); + AssertMetadataConsistency(info->mMetadata); + mMetadata = info->mMetadata; } - mDatabase = MakeSafeRefPtr( + mDatabase = MakeRefPtr( static_cast(Manager()), mCommonParams.principalInfo(), - mOptionalContentParentId, mGroup, mOrigin, mTelemetryId, - mMetadata.clonePtr(), mFileManager.clonePtr(), std::move(mDirectoryLock), - mFileHandleDisabled, mChromeWriteAccessAllowed); + mOptionalContentParentId, mGroup, mOrigin, mTelemetryId, mMetadata, + mFileManager, std::move(mDirectoryLock), mFileHandleDisabled, + mChromeWriteAccessAllowed); if (info) { - info->mLiveDatabases.AppendElement(mDatabase.unsafeGetRawPtr()); + info->mLiveDatabases.AppendElement(mDatabase); } else { - info = new DatabaseActorInfo(mMetadata.clonePtr(), - mDatabase.unsafeGetRawPtr()); + info = new DatabaseActorInfo(mMetadata, mDatabase); gLiveDatabaseHashtable->Put(mDatabaseId, info); } @@ -22392,8 +22313,7 @@ nsresult OpenDatabaseOp::EnsureDatabaseActorIsAlive() { // Transfer ownership to IPDL. mDatabase->SetActorAlive(); - if (!factory->SendPBackgroundIDBDatabaseConstructor( - mDatabase.unsafeGetRawPtr(), spec, this)) { + if (!factory->SendPBackgroundIDBDatabaseConstructor(mDatabase, spec, this)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } @@ -22431,39 +22351,41 @@ void OpenDatabaseOp::MetadataToSpec(DatabaseSpec& aSpec) { #ifdef DEBUG void OpenDatabaseOp::AssertMetadataConsistency( - const FullDatabaseMetadata& aMetadata) { + const FullDatabaseMetadata* aMetadata) { AssertIsOnBackgroundThread(); - const FullDatabaseMetadata& thisDB = *mMetadata; - const FullDatabaseMetadata& otherDB = aMetadata; + const FullDatabaseMetadata* thisDB = mMetadata; + const FullDatabaseMetadata* otherDB = aMetadata; - MOZ_ASSERT(&thisDB != &otherDB); + MOZ_ASSERT(thisDB); + MOZ_ASSERT(otherDB); + MOZ_ASSERT(thisDB != otherDB); - MOZ_ASSERT(thisDB.mCommonMetadata.name() == otherDB.mCommonMetadata.name()); - MOZ_ASSERT(thisDB.mCommonMetadata.version() == - otherDB.mCommonMetadata.version()); - MOZ_ASSERT(thisDB.mCommonMetadata.persistenceType() == - otherDB.mCommonMetadata.persistenceType()); - MOZ_ASSERT(thisDB.mDatabaseId == otherDB.mDatabaseId); - MOZ_ASSERT(thisDB.mFilePath == otherDB.mFilePath); + MOZ_ASSERT(thisDB->mCommonMetadata.name() == otherDB->mCommonMetadata.name()); + MOZ_ASSERT(thisDB->mCommonMetadata.version() == + otherDB->mCommonMetadata.version()); + MOZ_ASSERT(thisDB->mCommonMetadata.persistenceType() == + otherDB->mCommonMetadata.persistenceType()); + MOZ_ASSERT(thisDB->mDatabaseId == otherDB->mDatabaseId); + MOZ_ASSERT(thisDB->mFilePath == otherDB->mFilePath); // |thisDB| reflects the latest objectStore and index ids that have committed // to disk. The in-memory metadata |otherDB| keeps track of objectStores and // indexes that were created and then removed as well, so the next ids for // |otherDB| may be higher than for |thisDB|. - MOZ_ASSERT(thisDB.mNextObjectStoreId <= otherDB.mNextObjectStoreId); - MOZ_ASSERT(thisDB.mNextIndexId <= otherDB.mNextIndexId); + MOZ_ASSERT(thisDB->mNextObjectStoreId <= otherDB->mNextObjectStoreId); + MOZ_ASSERT(thisDB->mNextIndexId <= otherDB->mNextIndexId); - MOZ_ASSERT(thisDB.mObjectStores.Count() == otherDB.mObjectStores.Count()); + MOZ_ASSERT(thisDB->mObjectStores.Count() == otherDB->mObjectStores.Count()); - for (const auto& objectStoreEntry : thisDB.mObjectStores) { + for (const auto& objectStoreEntry : thisDB->mObjectStores) { FullObjectStoreMetadata* thisObjectStore = objectStoreEntry.GetData(); MOZ_ASSERT(thisObjectStore); MOZ_ASSERT(!thisObjectStore->mDeleted); auto* otherObjectStore = MetadataNameOrIdMatcher::Match( - otherDB.mObjectStores, thisObjectStore->mCommonMetadata.id()); + otherDB->mObjectStores, thisObjectStore->mCommonMetadata.id()); MOZ_ASSERT(otherObjectStore); MOZ_ASSERT(thisObjectStore != otherObjectStore); @@ -22812,7 +22734,7 @@ nsresult DeleteDatabaseOp::BeginVersionChange() { MOZ_ASSERT(!info->mWaitingFactoryOp); nsresult rv = - SendVersionChangeMessages(info, Nothing(), mPreviousVersion, Nothing()); + SendVersionChangeMessages(info, nullptr, mPreviousVersion, Nothing()); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -23004,25 +22926,20 @@ void DeleteDatabaseOp::VersionChangeOp::RunOnOwningThread() { if (info) { MOZ_ASSERT(!info->mLiveDatabases.IsEmpty()); - nsTArray> liveDatabases; - if (NS_WARN_IF(!liveDatabases.SetCapacity(info->mLiveDatabases.Length(), - fallible))) { + FallibleTArray liveDatabases; + if (NS_WARN_IF(!liveDatabases.AppendElements(info->mLiveDatabases, + fallible))) { deleteOp->SetFailureCode(NS_ERROR_OUT_OF_MEMORY); } else { - std::transform(info->mLiveDatabases.cbegin(), - info->mLiveDatabases.cend(), - MakeBackInserter(liveDatabases), - [](const auto& aDatabase) -> SafeRefPtr { - return {aDatabase, AcquireStrongRefFromRawPtr{}}; - }); - #ifdef DEBUG // The code below should result in the deletion of |info|. Set to null // here to make sure we find invalid uses later. info = nullptr; #endif - - for (const auto& database : liveDatabases) { + // TODO: Why do we convert to RefPtr here? If this is really + // necessary, this is very error-prone, and provide the type of + // liveDatabases should be changed. + for (RefPtr database : liveDatabases) { database->Invalidate(); } @@ -23065,7 +22982,7 @@ nsresult DeleteDatabaseOp::VersionChangeOp::Run() { } TransactionDatabaseOperationBase::TransactionDatabaseOperationBase( - SafeRefPtr aTransaction) + RefPtr aTransaction) : DatabaseOperationBase(aTransaction->GetLoggingInfo()->Id(), aTransaction->GetLoggingInfo()->NextRequestSN()), mTransaction(std::move(aTransaction)), @@ -23075,7 +22992,7 @@ TransactionDatabaseOperationBase::TransactionDatabaseOperationBase( } TransactionDatabaseOperationBase::TransactionDatabaseOperationBase( - SafeRefPtr aTransaction, uint64_t aLoggingSerialNumber) + RefPtr aTransaction, uint64_t aLoggingSerialNumber) : DatabaseOperationBase(aTransaction->GetLoggingInfo()->Id(), aLoggingSerialNumber), mTransaction(std::move(aTransaction)), @@ -23139,14 +23056,15 @@ void TransactionDatabaseOperationBase::RunOnConnectionThread() { IDB_REPORT_INTERNAL_ERR(); OverrideFailureCode(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); } else { - Database& database = (*mTransaction)->GetMutableDatabase(); + Database* database = (*mTransaction)->GetDatabase(); + MOZ_ASSERT(database); // Here we're actually going to perform the database operation. - nsresult rv = database.EnsureConnection(); + nsresult rv = database->EnsureConnection(); if (NS_WARN_IF(NS_FAILED(rv))) { SetFailureCode(rv); } else { - DatabaseConnection* connection = database.GetConnection(); + DatabaseConnection* connection = database->GetConnection(); MOZ_ASSERT(connection); MOZ_ASSERT(connection->GetStorageConnection()); @@ -23310,9 +23228,10 @@ void TransactionDatabaseOperationBase::SendPreprocessInfoOrResults( } } -bool TransactionDatabaseOperationBase::Init(TransactionBase& aTransaction) { +bool TransactionDatabaseOperationBase::Init(TransactionBase* aTransaction) { AssertIsOnBackgroundThread(); MOZ_ASSERT(mInternalState == InternalState::Initial); + MOZ_ASSERT(aTransaction); return true; } @@ -23321,7 +23240,7 @@ void TransactionDatabaseOperationBase::Cleanup() { AssertIsOnOwningThread(); MOZ_ASSERT(mInternalState == InternalState::SendingResults); - mTransaction.destroy(); + mTransaction.reset(); } NS_IMETHODIMP @@ -23348,13 +23267,13 @@ TransactionDatabaseOperationBase::Run() { } } -TransactionBase::CommitOp::CommitOp(SafeRefPtr aTransaction, +TransactionBase::CommitOp::CommitOp(TransactionBase* aTransaction, nsresult aResultCode) : DatabaseOperationBase(aTransaction->GetLoggingInfo()->Id(), aTransaction->GetLoggingInfo()->NextRequestSN()), - mTransaction(std::move(aTransaction)), + mTransaction(aTransaction), mResultCode(aResultCode) { - MOZ_ASSERT(mTransaction); + MOZ_ASSERT(aTransaction); MOZ_ASSERT(LoggingSerialNumber()); } @@ -23370,8 +23289,10 @@ nsresult TransactionBase::CommitOp::WriteAutoIncrementCounts() { mTransaction->mModifiedAutoIncrementObjectStoreMetadataArray; if (!metadataArray.IsEmpty()) { - DatabaseConnection* connection = - mTransaction->GetDatabase().GetConnection(); + Database* database = mTransaction->GetDatabase(); + MOZ_ASSERT(database); + + DatabaseConnection* connection = database->GetConnection(); MOZ_ASSERT(connection); DatabaseConnection::CachedStatement stmt; @@ -23490,8 +23411,10 @@ TransactionBase::CommitOp::Run() { if (mTransaction->GetMode() != IDBTransaction::Mode::ReadOnly && mTransaction->mHasBeenActiveOnConnectionThread) { - if (DatabaseConnection* connection = - mTransaction->GetDatabase().GetConnection()) { + Database* database = mTransaction->GetDatabase(); + MOZ_ASSERT(database); + + if (DatabaseConnection* connection = database->GetConnection()) { // May be null if the VersionChangeOp was canceled. DatabaseConnection::UpdateRefcountFunction* fileRefcountFunction = connection->GetUpdateRefcountFunction(); @@ -23581,7 +23504,10 @@ void TransactionBase::CommitOp::TransactionFinishedAfterUnblock() { mTransaction->SendCompleteNotification(ClampResultCode(mResultCode)); - mTransaction->GetMutableDatabase().UnregisterTransaction(*mTransaction); + Database* database = mTransaction->GetDatabase(); + MOZ_ASSERT(database); + + database->UnregisterTransaction(mTransaction); mTransaction = nullptr; @@ -23592,13 +23518,13 @@ void TransactionBase::CommitOp::TransactionFinishedAfterUnblock() { #endif } -DatabaseOp::DatabaseOp(SafeRefPtr aDatabase) +DatabaseOp::DatabaseOp(Database* aDatabase) : DatabaseOperationBase(aDatabase->GetLoggingInfo()->Id(), aDatabase->GetLoggingInfo()->NextRequestSN()), - mDatabase(std::move(aDatabase)), + mDatabase(aDatabase), mState(State::Initial) { AssertIsOnBackgroundThread(); - MOZ_ASSERT(mDatabase); + MOZ_ASSERT(aDatabase); } nsresult DatabaseOp::SendToIOThread() { @@ -23668,10 +23594,9 @@ void DatabaseOp::ActorDestroy(ActorDestroyReason aWhy) { NoteActorDestroyed(); } -CreateFileOp::CreateFileOp(SafeRefPtr aDatabase, +CreateFileOp::CreateFileOp(Database* aDatabase, const DatabaseRequestParams& aParams) - : DatabaseOp(std::move(aDatabase)), - mParams(aParams.get_CreateFileParams()) { + : DatabaseOp(aDatabase), mParams(aParams.get_CreateFileParams()) { MOZ_ASSERT(aParams.type() == DatabaseRequestParams::TCreateFileParams); } @@ -23683,7 +23608,7 @@ nsresult CreateFileOp::CreateMutableFile(RefPtr* aMutableFile) { } RefPtr mutableFile = - MutableFile::Create(file, mDatabase.clonePtr(), mFileInfo->clonePtr()); + MutableFile::Create(file, mDatabase, *mFileInfo); if (NS_WARN_IF(!mutableFile)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; @@ -23713,9 +23638,9 @@ nsresult CreateFileOp::DoDatabaseWork() { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } - FileManager& fileManager = mDatabase->GetFileManager(); + FileManager* fileManager = mDatabase->GetFileManager(); - mFileInfo.init(fileManager.CreateFileInfo()); + mFileInfo.init(fileManager->CreateFileInfo()); if (NS_WARN_IF(!*mFileInfo)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; @@ -23723,13 +23648,13 @@ nsresult CreateFileOp::DoDatabaseWork() { const int64_t fileId = (*mFileInfo)->Id(); - const auto journalDirectory = fileManager.EnsureJournalDirectory(); + const auto journalDirectory = fileManager->EnsureJournalDirectory(); if (NS_WARN_IF(!journalDirectory)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } - const auto journalFile = fileManager.GetFileForId(journalDirectory, fileId); + const auto journalFile = fileManager->GetFileForId(journalDirectory, fileId); if (NS_WARN_IF(!journalFile)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; @@ -23740,13 +23665,13 @@ nsresult CreateFileOp::DoDatabaseWork() { return rv; } - const auto fileDirectory = fileManager.GetDirectory(); + const auto fileDirectory = fileManager->GetDirectory(); if (NS_WARN_IF(!fileDirectory)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } - const auto file = fileManager.GetFileForId(fileDirectory, fileId); + const auto file = fileManager->GetFileForId(fileDirectory, fileId); if (NS_WARN_IF(!file)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; @@ -24184,12 +24109,12 @@ nsresult RenameObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection) { return NS_OK; } -CreateIndexOp::CreateIndexOp(SafeRefPtr aTransaction, +CreateIndexOp::CreateIndexOp(RefPtr aTransaction, const IndexOrObjectStoreId aObjectStoreId, const IndexMetadata& aMetadata) : VersionChangeTransactionOp(std::move(aTransaction)), mMetadata(aMetadata), - mFileManager(Transaction().GetDatabase().GetFileManagerPtr()), + mFileManager(Transaction().GetDatabase()->GetFileManager()), mDatabaseId(Transaction().DatabaseId()), mObjectStoreId(aObjectStoreId) { MOZ_ASSERT(aObjectStoreId); @@ -24263,8 +24188,9 @@ nsresult CreateIndexOp::InsertDataFromObjectStoreInternal( return NS_OK; } -bool CreateIndexOp::Init(TransactionBase& aTransaction) { +bool CreateIndexOp::Init(TransactionBase* aTransaction) { AssertIsOnBackgroundThread(); + MOZ_ASSERT(aTransaction); nsresult rv = GetUniqueIndexTableForObjectStore(aTransaction, mObjectStoreId, mMaybeUniqueIndexTable); @@ -24585,7 +24511,7 @@ CreateIndexOp::UpdateIndexDataValuesFunction::OnFunctionCall( return NS_OK; } -DeleteIndexOp::DeleteIndexOp(SafeRefPtr aTransaction, +DeleteIndexOp::DeleteIndexOp(RefPtr aTransaction, const IndexOrObjectStoreId aObjectStoreId, const IndexOrObjectStoreId aIndexId, const bool aUnique, const bool aIsLastIndex) @@ -25263,15 +25189,15 @@ mozilla::ipc::IPCResult NormalTransactionOp::RecvContinue( } ObjectStoreAddOrPutRequestOp::ObjectStoreAddOrPutRequestOp( - SafeRefPtr aTransaction, RequestParams&& aParams) + RefPtr aTransaction, RequestParams&& aParams) : NormalTransactionOp(std::move(aTransaction)), mParams( std::move(aParams.type() == RequestParams::TObjectStoreAddParams ? aParams.get_ObjectStoreAddParams().commonParams() : aParams.get_ObjectStorePutParams().commonParams())), - mGroup(Transaction().GetDatabase().Group()), - mOrigin(Transaction().GetDatabase().Origin()), - mPersistenceType(Transaction().GetDatabase().Type()), + mGroup(Transaction().GetDatabase()->Group()), + mOrigin(Transaction().GetDatabase()->Origin()), + mPersistenceType(Transaction().GetDatabase()->Type()), mOverwrite(aParams.type() == RequestParams::TObjectStorePutParams), mObjectStoreMayHaveIndexes(false) { MOZ_ASSERT(aParams.type() == RequestParams::TObjectStoreAddParams || @@ -25351,7 +25277,7 @@ nsresult ObjectStoreAddOrPutRequestOp::RemoveOldIndexDataValues( return NS_OK; } -bool ObjectStoreAddOrPutRequestOp::Init(TransactionBase& aTransaction) { +bool ObjectStoreAddOrPutRequestOp::Init(TransactionBase* aTransaction) { AssertIsOnOwningThread(); const nsTArray& indexUpdateInfos = @@ -25396,13 +25322,13 @@ bool ObjectStoreAddOrPutRequestOp::Init(TransactionBase& aTransaction) { } for (const auto& fileAddInfo : fileAddInfos) { - MOZ_ASSERT(fileAddInfo.type() == StructuredCloneFileBase::eBlob || - fileAddInfo.type() == StructuredCloneFileBase::eMutableFile); + MOZ_ASSERT(fileAddInfo.type() == StructuredCloneFile::eBlob || + fileAddInfo.type() == StructuredCloneFile::eMutableFile); const DatabaseOrMutableFile& file = fileAddInfo.file(); switch (fileAddInfo.type()) { - case StructuredCloneFileBase::eBlob: { + case StructuredCloneFile::eBlob: { MOZ_ASSERT(file.type() == DatabaseOrMutableFile::TPBackgroundIDBDatabaseFileParent); @@ -25411,11 +25337,11 @@ bool ObjectStoreAddOrPutRequestOp::Init(TransactionBase& aTransaction) { MOZ_ASSERT(fileActor); mStoredFileInfos.EmplaceBack(StoredFileInfo::CreateForBlob( - fileActor->GetFileInfoPtr(), fileActor)); + fileActor->GetFileInfo(), fileActor)); break; } - case StructuredCloneFileBase::eMutableFile: { + case StructuredCloneFile::eMutableFile: { MOZ_ASSERT(file.type() == DatabaseOrMutableFile::TPBackgroundMutableFileParent); @@ -25424,7 +25350,7 @@ bool ObjectStoreAddOrPutRequestOp::Init(TransactionBase& aTransaction) { MOZ_ASSERT(mutableFileActor); mStoredFileInfos.EmplaceBack(StoredFileInfo::CreateForMutableFile( - mutableFileActor->GetFileInfoPtr())); + mutableFileActor->GetFileInfo())); break; } @@ -25437,7 +25363,7 @@ bool ObjectStoreAddOrPutRequestOp::Init(TransactionBase& aTransaction) { if (mDataOverThreshold) { mStoredFileInfos.EmplaceBack(StoredFileInfo::CreateForStructuredClone( - aTransaction.GetDatabase().GetFileManager().CreateFileInfo(), + aTransaction->GetDatabase()->GetFileManager()->CreateFileInfo(), MakeRefPtr(mParams.cloneInfo().data().data))); } @@ -25638,7 +25564,11 @@ nsresult ObjectStoreAddOrPutRequestOp::DoDatabaseWork( if (inputStream) { if (fileHelper.isNothing()) { - fileHelper.emplace(Transaction().GetDatabase().GetFileManagerPtr()); + RefPtr fileManager = + Transaction().GetDatabase()->GetFileManager(); + MOZ_ASSERT(fileManager); + + fileHelper.emplace(fileManager); rv = fileHelper->Init(); if (NS_WARN_IF(NS_FAILED(rv))) { IDB_REPORT_INTERNAL_ERR(); @@ -25662,7 +25592,7 @@ nsresult ObjectStoreAddOrPutRequestOp::DoDatabaseWork( const bool compress = storedFileInfo.ShouldCompress(); - rv = fileHelper->CreateFileFromStream(*file, *journalFile, *inputStream, + rv = fileHelper->CreateFileFromStream(file, journalFile, inputStream, compress); if (NS_FAILED(rv) && NS_ERROR_GET_MODULE(rv) != NS_ERROR_MODULE_DOM_INDEXEDDB) { @@ -25671,7 +25601,7 @@ nsresult ObjectStoreAddOrPutRequestOp::DoDatabaseWork( } if (NS_WARN_IF(NS_FAILED(rv))) { // Try to remove the file if the copy failed. - nsresult rv2 = fileHelper->RemoveFile(*file, *journalFile); + nsresult rv2 = fileHelper->RemoveFile(file, journalFile); if (NS_WARN_IF(NS_FAILED(rv2))) { return rv; } @@ -25824,13 +25754,13 @@ ObjectStoreAddOrPutRequestOp::SCInputStream::IsNonBlocking(bool* _retval) { } ObjectStoreGetRequestOp::ObjectStoreGetRequestOp( - SafeRefPtr aTransaction, const RequestParams& aParams, + RefPtr aTransaction, const RequestParams& aParams, bool aGetAll) : NormalTransactionOp(std::move(aTransaction)), mObjectStoreId(aGetAll ? aParams.get_ObjectStoreGetAllParams().objectStoreId() : aParams.get_ObjectStoreGetParams().objectStoreId()), - mDatabase(Transaction().GetDatabasePtr()), + mDatabase(Transaction().GetDatabase()), mOptionalKeyRange( aGetAll ? aParams.get_ObjectStoreGetAllParams().optionalKeyRange() : Some(aParams.get_ObjectStoreGetParams().keyRange())), @@ -25925,7 +25855,7 @@ nsresult ObjectStoreGetRequestOp::DoDatabaseWork( bool hasResult; while (NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) { auto cloneInfoOrErr = GetStructuredCloneReadInfoFromStatement( - &*stmt, 1, 0, mDatabase->GetFileManager()); + &*stmt, 1, 0, *mDatabase->GetFileManager()); if (NS_WARN_IF(cloneInfoOrErr.isErr())) { return Err(cloneInfoOrErr.unwrapErr()); } @@ -26050,7 +25980,7 @@ void ObjectStoreGetRequestOp::GetResponse(RequestResponse& aResponse, } ObjectStoreGetKeyRequestOp::ObjectStoreGetKeyRequestOp( - SafeRefPtr aTransaction, const RequestParams& aParams, + RefPtr aTransaction, const RequestParams& aParams, bool aGetAll) : NormalTransactionOp(std::move(aTransaction)), mObjectStoreId( @@ -26157,7 +26087,7 @@ void ObjectStoreGetKeyRequestOp::GetResponse(RequestResponse& aResponse, } ObjectStoreDeleteRequestOp::ObjectStoreDeleteRequestOp( - SafeRefPtr aTransaction, + RefPtr aTransaction, const ObjectStoreDeleteParams& aParams) : NormalTransactionOp(std::move(aTransaction)), mParams(aParams), @@ -26239,8 +26169,7 @@ nsresult ObjectStoreDeleteRequestOp::DoDatabaseWork( } ObjectStoreClearRequestOp::ObjectStoreClearRequestOp( - SafeRefPtr aTransaction, - const ObjectStoreClearParams& aParams) + RefPtr aTransaction, const ObjectStoreClearParams& aParams) : NormalTransactionOp(std::move(aTransaction)), mParams(aParams), mObjectStoreMayHaveIndexes(false) { @@ -26432,10 +26361,10 @@ RefPtr IndexRequestOpBase::IndexMetadataForParams( return indexMetadata; } -IndexGetRequestOp::IndexGetRequestOp(SafeRefPtr aTransaction, +IndexGetRequestOp::IndexGetRequestOp(RefPtr aTransaction, const RequestParams& aParams, bool aGetAll) : IndexRequestOpBase(std::move(aTransaction), aParams), - mDatabase(Transaction().GetDatabasePtr()), + mDatabase(Transaction().GetDatabase()), mOptionalKeyRange(aGetAll ? aParams.get_IndexGetAllParams().optionalKeyRange() : Some(aParams.get_IndexGetParams().keyRange())), @@ -26511,7 +26440,7 @@ nsresult IndexGetRequestOp::DoDatabaseWork(DatabaseConnection* aConnection) { bool hasResult; while (NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) { auto cloneInfoOrErr = GetStructuredCloneReadInfoFromStatement( - &*stmt, 1, 0, mDatabase->GetFileManager()); + &*stmt, 1, 0, *mDatabase->GetFileManager()); if (NS_WARN_IF(cloneInfoOrErr.isErr())) { return cloneInfoOrErr.unwrapErr(); } @@ -26553,7 +26482,7 @@ void IndexGetRequestOp::GetResponse(RequestResponse& aResponse, for (uint32_t count = mResponse.Length(), index = 0; index < count; index++) { - StructuredCloneReadInfoParent& info = mResponse[index]; + StructuredCloneReadInfo& info = mResponse[index]; *aResponseSize += info.Size(); SerializedStructuredCloneReadInfo& serializedInfo = @@ -26587,7 +26516,7 @@ void IndexGetRequestOp::GetResponse(RequestResponse& aResponse, *aResponseSize = 0; if (!mResponse.IsEmpty()) { - StructuredCloneReadInfoParent& info = mResponse[0]; + StructuredCloneReadInfo& info = mResponse[0]; *aResponseSize += info.Size(); SerializedStructuredCloneReadInfo& serializedInfo = @@ -26609,9 +26538,9 @@ void IndexGetRequestOp::GetResponse(RequestResponse& aResponse, } } -IndexGetKeyRequestOp::IndexGetKeyRequestOp( - SafeRefPtr aTransaction, const RequestParams& aParams, - bool aGetAll) +IndexGetKeyRequestOp::IndexGetKeyRequestOp(RefPtr aTransaction, + const RequestParams& aParams, + bool aGetAll) : IndexRequestOpBase(std::move(aTransaction), aParams), mOptionalKeyRange( aGetAll ? aParams.get_IndexGetAllKeysParams().optionalKeyRange() @@ -27805,6 +27734,7 @@ DEBUGThreadSlower::AfterProcessNextEvent(nsIThreadInternal* /* aThread */, nsresult FileHelper::Init() { MOZ_ASSERT(!IsOnBackgroundThread()); + MOZ_ASSERT(mFileManager); auto fileDirectory = mFileManager->GetCheckedDirectory(); if (NS_WARN_IF(!fileDirectory)) { @@ -27824,31 +27754,47 @@ nsresult FileHelper::Init() { MOZ_ASSERT(NS_SUCCEEDED(journalDirectory->IsDirectory(&isDirectory))); MOZ_ASSERT(isDirectory); - mFileDirectory.init(std::move(fileDirectory)); - mJournalDirectory.init(std::move(journalDirectory)); + mFileDirectory = std::move(fileDirectory); + mJournalDirectory = std::move(journalDirectory); return NS_OK; } nsCOMPtr FileHelper::GetFile(const FileInfo& aFileInfo) { MOZ_ASSERT(!IsOnBackgroundThread()); + MOZ_ASSERT(mFileManager); + MOZ_ASSERT(mFileDirectory); - return mFileManager->GetFileForId(*mFileDirectory, aFileInfo.Id()); + const int64_t fileId = aFileInfo.Id(); + MOZ_ASSERT(fileId > 0); + + return mFileManager->GetFileForId(mFileDirectory, fileId); } nsCOMPtr FileHelper::GetJournalFile(const FileInfo& aFileInfo) { MOZ_ASSERT(!IsOnBackgroundThread()); + MOZ_ASSERT(mFileManager); + MOZ_ASSERT(mJournalDirectory); - return mFileManager->GetFileForId(*mJournalDirectory, aFileInfo.Id()); + const int64_t fileId = aFileInfo.Id(); + MOZ_ASSERT(fileId > 0); + + return mFileManager->GetFileForId(mJournalDirectory, fileId); } -nsresult FileHelper::CreateFileFromStream(nsIFile& aFile, nsIFile& aJournalFile, - nsIInputStream& aInputStream, +nsresult FileHelper::CreateFileFromStream(nsIFile* aFile, nsIFile* aJournalFile, + nsIInputStream* aInputStream, bool aCompress) { MOZ_ASSERT(!IsOnBackgroundThread()); + MOZ_ASSERT(aFile); + MOZ_ASSERT(aJournalFile); + MOZ_ASSERT(aInputStream); + MOZ_ASSERT(mFileManager); + MOZ_ASSERT(mFileDirectory); + MOZ_ASSERT(mJournalDirectory); bool exists; - nsresult rv = aFile.Exists(&exists); + nsresult rv = aFile->Exists(&exists); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -27867,7 +27813,7 @@ nsresult FileHelper::CreateFileFromStream(nsIFile& aFile, nsIFile& aJournalFile, // This corner case is partially simulated in test_file_copy_failure.js if (exists) { bool isFile; - rv = aFile.IsFile(&isFile); + rv = aFile->IsFile(&isFile); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -27876,7 +27822,7 @@ nsresult FileHelper::CreateFileFromStream(nsIFile& aFile, nsIFile& aJournalFile, return NS_ERROR_FAILURE; } - rv = aJournalFile.Exists(&exists); + rv = aJournalFile->Exists(&exists); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -27885,7 +27831,7 @@ nsresult FileHelper::CreateFileFromStream(nsIFile& aFile, nsIFile& aJournalFile, return NS_ERROR_FAILURE; } - rv = aJournalFile.IsFile(&isFile); + rv = aJournalFile->IsFile(&isFile); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -27903,7 +27849,7 @@ nsresult FileHelper::CreateFileFromStream(nsIFile& aFile, nsIFile& aJournalFile, } // Create a journal file first. - rv = aJournalFile.Create(nsIFile::NORMAL_FILE_TYPE, 0644); + rv = aJournalFile->Create(nsIFile::NORMAL_FILE_TYPE, 0644); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -27911,29 +27857,24 @@ nsresult FileHelper::CreateFileFromStream(nsIFile& aFile, nsIFile& aJournalFile, // Now try to copy the stream. RefPtr fileOutputStream = CreateFileOutputStream(mFileManager->Type(), mFileManager->Group(), - mFileManager->Origin(), Client::IDB, &aFile); + mFileManager->Origin(), Client::IDB, aFile); if (NS_WARN_IF(!fileOutputStream)) { return NS_ERROR_FAILURE; } - AutoTArray buffer; - const auto actualOutputStream = - [aCompress, &buffer, &fileOutputStream]() -> nsCOMPtr { - if (aCompress) { - auto snappyOutputStream = - MakeRefPtr(fileOutputStream); + if (aCompress) { + RefPtr snappyOutputStream = + new SnappyCompressOutputStream(fileOutputStream); - buffer.SetLength(snappyOutputStream->BlockSize()); + UniquePtr buffer(new char[snappyOutputStream->BlockSize()]); - return snappyOutputStream; - } + rv = SyncCopy(aInputStream, snappyOutputStream, buffer.get(), + snappyOutputStream->BlockSize()); + } else { + char buffer[kFileCopyBufferSize]; - buffer.SetLength(kFileCopyBufferSize); - return std::move(fileOutputStream); - }(); - - rv = SyncCopy(aInputStream, *actualOutputStream, buffer.Elements(), - buffer.Length()); + rv = SyncCopy(aInputStream, fileOutputStream, buffer, kFileCopyBufferSize); + } if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -27941,19 +27882,19 @@ nsresult FileHelper::CreateFileFromStream(nsIFile& aFile, nsIFile& aJournalFile, return NS_OK; } -nsresult FileHelper::RemoveFile(nsIFile& aFile, nsIFile& aJournalFile) { +nsresult FileHelper::RemoveFile(nsIFile* aFile, nsIFile* aJournalFile) { nsresult rv; int64_t fileSize; if (mFileManager->EnforcingQuota()) { - rv = aFile.GetFileSize(&fileSize); + rv = aFile->GetFileSize(&fileSize); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } - rv = aFile.Remove(false); + rv = aFile->Remove(false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -27967,7 +27908,7 @@ nsresult FileHelper::RemoveFile(nsIFile& aFile, nsIFile& aJournalFile) { Client::IDB, fileSize); } - rv = aJournalFile.Remove(false); + rv = aJournalFile->Remove(false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -28028,25 +27969,25 @@ NS_INTERFACE_MAP_BEGIN(FileHelper::ReadCallback) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStreamCallback) NS_INTERFACE_MAP_END -nsresult FileHelper::SyncRead(nsIInputStream& aInputStream, char* const aBuffer, - const uint32_t aBufferSize, - uint32_t* const aRead) { +nsresult FileHelper::SyncRead(nsIInputStream* aInputStream, char* aBuffer, + uint32_t aBufferSize, uint32_t* aRead) { MOZ_ASSERT(!IsOnBackgroundThread()); + MOZ_ASSERT(aInputStream); // Let's try to read, directly. - nsresult rv = aInputStream.Read(aBuffer, aBufferSize, aRead); + nsresult rv = aInputStream->Read(aBuffer, aBufferSize, aRead); if (NS_SUCCEEDED(rv) || rv != NS_BASE_STREAM_WOULD_BLOCK) { return rv; } // We need to proceed async. - nsCOMPtr asyncStream = do_QueryInterface(&aInputStream); + nsCOMPtr asyncStream = do_QueryInterface(aInputStream); if (!asyncStream) { return rv; } if (!mReadCallback) { - mReadCallback.init(new ReadCallback()); + mReadCallback = new ReadCallback(); } // We just need any thread with an event loop for receiving the @@ -28055,7 +27996,7 @@ nsresult FileHelper::SyncRead(nsIInputStream& aInputStream, char* const aBuffer, do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); MOZ_ASSERT(target); - rv = (*mReadCallback)->AsyncWait(asyncStream, aBufferSize, target); + rv = mReadCallback->AsyncWait(asyncStream, aBufferSize, target); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -28063,10 +28004,12 @@ nsresult FileHelper::SyncRead(nsIInputStream& aInputStream, char* const aBuffer, return SyncRead(aInputStream, aBuffer, aBufferSize, aRead); } -nsresult FileHelper::SyncCopy(nsIInputStream& aInputStream, - nsIOutputStream& aOutputStream, - char* const aBuffer, const uint32_t aBufferSize) { +nsresult FileHelper::SyncCopy(nsIInputStream* aInputStream, + nsIOutputStream* aOutputStream, char* aBuffer, + uint32_t aBufferSize) { MOZ_ASSERT(!IsOnBackgroundThread()); + MOZ_ASSERT(aInputStream); + MOZ_ASSERT(aOutputStream); AUTO_PROFILER_LABEL("FileHelper::SyncCopy", DOM); @@ -28084,7 +28027,7 @@ nsresult FileHelper::SyncCopy(nsIInputStream& aInputStream, } uint32_t numWrite; - rv = aOutputStream.Write(aBuffer, numRead, &numWrite); + rv = aOutputStream->Write(aBuffer, numRead, &numWrite); if (rv == NS_ERROR_FILE_NO_DEVICE_SPACE) { rv = NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR; } @@ -28099,13 +28042,13 @@ nsresult FileHelper::SyncCopy(nsIInputStream& aInputStream, } while (true); if (NS_SUCCEEDED(rv)) { - rv = aOutputStream.Flush(); + rv = aOutputStream->Flush(); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } - nsresult rv2 = aOutputStream.Close(); + nsresult rv2 = aOutputStream->Close(); if (NS_WARN_IF(NS_FAILED(rv2))) { return NS_SUCCEEDED(rv) ? rv2 : rv; } diff --git a/dom/indexedDB/FileInfoT.h b/dom/indexedDB/FileInfoT.h index 5422d2dd2936..2f973f1afce4 100644 --- a/dom/indexedDB/FileInfoT.h +++ b/dom/indexedDB/FileInfoT.h @@ -9,7 +9,6 @@ #include "nsISupportsImpl.h" #include "nsCOMPtr.h" -#include "SafeRefPtr.h" namespace mozilla { namespace dom { @@ -21,7 +20,7 @@ class FileInfoT final { using AutoLock = typename FileManager::AutoLock; FileInfoT(const typename FileManager::FileManagerGuard& aGuard, - SafeRefPtr aFileManager, const int64_t aFileId, + RefPtr aFileManager, const int64_t aFileId, const nsrefcnt aInitialDBRefCnt = 0); void AddRef(); @@ -31,7 +30,7 @@ class FileInfoT final { void GetReferences(int32_t* aRefCnt, int32_t* aDBRefCnt); - FileManager& Manager() const; + FileManager* Manager() const; int64_t Id() const; @@ -50,7 +49,7 @@ class FileInfoT final { ThreadSafeAutoRefCnt mRefCnt; ThreadSafeAutoRefCnt mDBRefCnt; - const SafeRefPtr mFileManager; + const RefPtr mFileManager; }; } // namespace indexedDB diff --git a/dom/indexedDB/FileInfoTImpl.h b/dom/indexedDB/FileInfoTImpl.h index f2ebb6f22c16..1195518d8241 100644 --- a/dom/indexedDB/FileInfoTImpl.h +++ b/dom/indexedDB/FileInfoTImpl.h @@ -19,7 +19,7 @@ namespace indexedDB { template FileInfoT::FileInfoT( const typename FileManager::FileManagerGuard& aGuard, - SafeRefPtr aFileManager, const int64_t aFileId, + RefPtr aFileManager, const int64_t aFileId, const nsrefcnt aInitialDBRefCnt) : mFileId(aFileId), mDBRefCnt(aInitialDBRefCnt), @@ -58,8 +58,8 @@ void FileInfoT::GetReferences(int32_t* const aRefCnt, } template -FileManager& FileInfoT::Manager() const { - return *mFileManager; +FileManager* FileInfoT::Manager() const { + return mFileManager; } template @@ -136,7 +136,7 @@ void FileInfoT::Cleanup() { template nsCOMPtr FileInfoT::GetFileForFileInfo() const { - const nsCOMPtr directory = Manager().GetDirectory(); + const nsCOMPtr directory = Manager()->GetDirectory(); if (NS_WARN_IF(!directory)) { return nullptr; } diff --git a/dom/indexedDB/FileManager.h b/dom/indexedDB/FileManager.h index 83ced39d3481..fd6c0198c6eb 100644 --- a/dom/indexedDB/FileManager.h +++ b/dom/indexedDB/FileManager.h @@ -8,8 +8,8 @@ #define mozilla_dom_indexeddb_filemanager_h__ #include "mozilla/dom/quota/PersistenceType.h" -#include "mozilla/InitializedOnce.h" #include "FileManagerBase.h" +#include "InitializedOnce.h" class nsIFile; class mozIStorageConnection; @@ -28,8 +28,8 @@ class FileManager final : public FileManagerBase { const nsCString mOrigin; const nsString mDatabaseName; - LazyInitializedOnce mDirectoryPath; - LazyInitializedOnce mJournalDirectoryPath; + InitializedOnce mDirectoryPath; + InitializedOnce mJournalDirectoryPath; const bool mEnforcingQuota; diff --git a/dom/indexedDB/FileManagerBase.h b/dom/indexedDB/FileManagerBase.h index 741d2bd4e671..6dd3d2d42bc1 100644 --- a/dom/indexedDB/FileManagerBase.h +++ b/dom/indexedDB/FileManagerBase.h @@ -27,13 +27,13 @@ class FileManagerBase { using MutexType = StaticMutex; using AutoLock = mozilla::detail::BaseAutoLock; - MOZ_MUST_USE SafeRefPtr GetFileInfo(int64_t aId) const { + MOZ_MUST_USE RefPtr GetFileInfo(int64_t aId) const { if (!AssertValid()) { // In release, the assertions are disabled. return nullptr; } - // TODO: We cannot simply change this to SafeRefPtr, because + // TODO: We cannot simply change this to RefPtr, because // FileInfo::AddRef also acquires the FileManager::Mutex. // This looks quirky at least. FileInfo* fileInfo; @@ -42,16 +42,16 @@ class FileManagerBase { fileInfo = mFileInfos.Get(aId); } - return {fileInfo, AcquireStrongRefFromRawPtr{}}; + return fileInfo; } - MOZ_MUST_USE SafeRefPtr CreateFileInfo() { + MOZ_MUST_USE RefPtr CreateFileInfo() { if (!AssertValid()) { // In release, the assertions are disabled. return nullptr; } - // TODO: We cannot simply change this to SafeRefPtr, because + // TODO: We cannot simply change this to RefPtr, because // FileInfo::AddRef also acquires the FileManager::Mutex. // This looks quirky at least. FileInfo* fileInfo; @@ -60,15 +60,13 @@ class FileManagerBase { const int64_t id = ++mLastFileId; - fileInfo = new FileInfo(FileManagerGuard{}, - SafeRefPtr{static_cast(this), - AcquireStrongRefFromRawPtr{}}, - id); + fileInfo = + new FileInfo(FileManagerGuard{}, static_cast(this), id); mFileInfos.Put(id, fileInfo); } - return {fileInfo, AcquireStrongRefFromRawPtr{}}; + return fileInfo; } void RemoveFileInfo(const int64_t aId, const AutoLock& aFileMutexLock) { diff --git a/dom/indexedDB/IDBCursor.h b/dom/indexedDB/IDBCursor.h index 7d1cc801ff8b..3376f9c7fcb8 100644 --- a/dom/indexedDB/IDBCursor.h +++ b/dom/indexedDB/IDBCursor.h @@ -9,13 +9,13 @@ #include "IDBCursorType.h" #include "IndexedDatabase.h" +#include "InitializedOnce.h" #include "js/RootingAPI.h" #include "mozilla/Attributes.h" #include "mozilla/dom/IDBCursorBinding.h" #include "mozilla/dom/IDBTransaction.h" #include "mozilla/dom/indexedDB/Key.h" #include "mozilla/dom/quota/CheckedUnsafePtr.h" -#include "mozilla/InitializedOnce.h" #include "nsCycleCollectionParticipant.h" #include "nsWrapperCache.h" @@ -52,7 +52,7 @@ class IDBCursor : public nsISupports, public nsWrapperCache { using Type = IDBCursorType; protected: - InitializedOnceNotNull + InitializedOnceMustBeTrue mBackgroundActor; // TODO: mRequest could be made const if Bug 1575173 is resolved. It is @@ -144,7 +144,7 @@ class IDBCursor : public nsISupports, public nsWrapperCache { void ClearBackgroundActor() { AssertIsOnOwningThread(); - mBackgroundActor.destroy(); + mBackgroundActor.reset(); } virtual void InvalidateCachedResponses() = 0; diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index 21a0eadabc9e..a90b03a6cbc6 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -79,7 +79,7 @@ IndexUpdateInfo MakeIndexUpdateInfo(const int64_t aIndexID, const Key& aKey, struct IDBObjectStore::StructuredCloneWriteInfo { JSAutoStructuredCloneBuffer mCloneBuffer; - nsTArray mFiles; + nsTArray mFiles; IDBDatabase* mDatabase; uint64_t mOffsetToKeyProp; @@ -117,7 +117,7 @@ struct IDBObjectStore::StructuredCloneWriteInfo { // what strong references have been acquired so that they can be freed even // if a de-serialization does not occur. struct IDBObjectStore::StructuredCloneInfo { - nsTArray mFiles; + nsTArray mFiles; }; namespace { @@ -229,7 +229,7 @@ bool StructuredCloneWriteCallback(JSContext* aCx, return false; } - const DebugOnly newFile = + const DebugOnly newFile = cloneWriteInfo->mFiles.EmplaceBack(mutableFile); MOZ_ASSERT(newFile); @@ -293,9 +293,8 @@ bool StructuredCloneWriteCallback(JSContext* aCx, } } - const DebugOnly newFile = - cloneWriteInfo->mFiles.EmplaceBack(StructuredCloneFileBase::eBlob, - blob); + const DebugOnly newFile = + cloneWriteInfo->mFiles.EmplaceBack(StructuredCloneFile::eBlob, blob); MOZ_ASSERT(newFile); return true; @@ -338,8 +337,8 @@ bool CopyingStructuredCloneWriteCallback(JSContext* aCx, return false; } - const DebugOnly newFile = - cloneInfo->mFiles.EmplaceBack(StructuredCloneFileBase::eBlob, blob); + const DebugOnly newFile = + cloneInfo->mFiles.EmplaceBack(StructuredCloneFile::eBlob, blob); MOZ_ASSERT(newFile); return true; @@ -361,7 +360,7 @@ bool CopyingStructuredCloneWriteCallback(JSContext* aCx, return false; } - const DebugOnly newFile = + const DebugOnly newFile = cloneInfo->mFiles.EmplaceBack(mutableFile); MOZ_ASSERT(newFile); @@ -422,17 +421,17 @@ JSObject* CopyingStructuredCloneReadCallback( return nullptr; } - StructuredCloneFileChild& file = cloneInfo->mFiles[aData]; + StructuredCloneFile& file = cloneInfo->mFiles[aData]; switch (static_cast(aTag)) { case SCTAG_DOM_BLOB: - MOZ_ASSERT(file.Type() == StructuredCloneFileBase::eBlob); + MOZ_ASSERT(file.Type() == StructuredCloneFile::eBlob); MOZ_ASSERT(!file.Blob().IsFile()); return WrapAsJSObject(aCx, file.MutableBlob()); case SCTAG_DOM_FILE: { - MOZ_ASSERT(file.Type() == StructuredCloneFileBase::eBlob); + MOZ_ASSERT(file.Type() == StructuredCloneFile::eBlob); JS::Rooted result(aCx); @@ -454,7 +453,7 @@ JSObject* CopyingStructuredCloneReadCallback( } case SCTAG_DOM_MUTABLEFILE: - MOZ_ASSERT(file.Type() == StructuredCloneFileBase::eMutableFile); + MOZ_ASSERT(file.Type() == StructuredCloneFile::eMutableFile); return WrapAsJSObject(aCx, file.MutableMutableFile()); @@ -607,8 +606,7 @@ void IDBObjectStore::AppendIndexUpdateInfo( } // static -void IDBObjectStore::ClearCloneReadInfo( - StructuredCloneReadInfoChild& aReadInfo) { +void IDBObjectStore::ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo) { // This is kind of tricky, we only want to release stuff on the main thread, // but we can end up being called on other threads if we have already been // cleared on the main thread. @@ -828,7 +826,7 @@ RefPtr IDBObjectStore::AddOrPut(JSContext* aCx, commonParams.indexUpdateInfos().SwapElements(updateInfo); // Convert any blobs or mutable files into FileAddInfo. - nsTArray& files = cloneWriteInfo.mFiles; + nsTArray& files = cloneWriteInfo.mFiles; if (!files.IsEmpty()) { const uint32_t count = files.Length(); @@ -842,13 +840,13 @@ RefPtr IDBObjectStore::AddOrPut(JSContext* aCx, IDBDatabase* const database = mTransaction->Database(); for (uint32_t index = 0; index < count; index++) { - StructuredCloneFileChild& file = files[index]; + StructuredCloneFile& file = files[index]; FileAddInfo* const fileAddInfo = fileAddInfos.AppendElement(fallible); MOZ_ASSERT(fileAddInfo); switch (file.Type()) { - case StructuredCloneFileBase::eBlob: { + case StructuredCloneFile::eBlob: { MOZ_ASSERT(file.HasBlob()); MOZ_ASSERT(!file.HasMutableFile()); @@ -861,12 +859,12 @@ RefPtr IDBObjectStore::AddOrPut(JSContext* aCx, } fileAddInfo->file() = fileActor; - fileAddInfo->type() = StructuredCloneFileBase::eBlob; + fileAddInfo->type() = StructuredCloneFile::eBlob; break; } - case StructuredCloneFileBase::eMutableFile: { + case StructuredCloneFile::eMutableFile: { MOZ_ASSERT(file.HasMutableFile()); MOZ_ASSERT(!file.HasBlob()); @@ -879,13 +877,13 @@ RefPtr IDBObjectStore::AddOrPut(JSContext* aCx, } fileAddInfo->file() = mutableFileActor; - fileAddInfo->type() = StructuredCloneFileBase::eMutableFile; + fileAddInfo->type() = StructuredCloneFile::eMutableFile; break; } - case StructuredCloneFileBase::eWasmBytecode: - case StructuredCloneFileBase::eWasmCompiled: { + case StructuredCloneFile::eWasmBytecode: + case StructuredCloneFile::eWasmCompiled: { MOZ_ASSERT(file.HasBlob()); MOZ_ASSERT(!file.HasMutableFile()); diff --git a/dom/indexedDB/IDBObjectStore.h b/dom/indexedDB/IDBObjectStore.h index 90ba2990b253..2dac06e78209 100644 --- a/dom/indexedDB/IDBObjectStore.h +++ b/dom/indexedDB/IDBObjectStore.h @@ -104,8 +104,7 @@ class IDBObjectStore final : public nsISupports, public nsWrapperCache { nsTArray* aUpdateInfoArray, ErrorResult* aRv); - static void ClearCloneReadInfo( - indexedDB::StructuredCloneReadInfoChild& aReadInfo); + static void ClearCloneReadInfo(indexedDB::StructuredCloneReadInfo& aReadInfo); static bool DeserializeValue(JSContext* aCx, StructuredCloneReadInfoChild&& aCloneReadInfo, diff --git a/dom/indexedDB/IndexedDatabase.cpp b/dom/indexedDB/IndexedDatabase.cpp index 80a05018b5ca..8229fcac9322 100644 --- a/dom/indexedDB/IndexedDatabase.cpp +++ b/dom/indexedDB/IndexedDatabase.cpp @@ -175,32 +175,42 @@ bool ReadWasmModule(JSStructuredCloneReader* aReader, WasmModuleData* aRetval) { return true; } -template -class ValueDeserializationHelper; - -class ValueDeserializationHelperBase { +class ValueDeserializationHelper { public: - static bool CreateAndWrapWasmModule(JSContext* aCx, - const StructuredCloneFileBase& aFile, - const WasmModuleData& aData, - JS::MutableHandle aResult) { + static bool CreateAndWrapMutableFile(JSContext* aCx, + StructuredCloneFile& aFile, + const MutableFileData& aData, + JS::MutableHandle aResult) { MOZ_ASSERT(aCx); - MOZ_ASSERT(aFile.Type() == StructuredCloneFileBase::eWasmBytecode); - // Both on the parent and child side, just create a plain object here, - // support for de-serialization of WebAssembly.Modules has been removed in - // bug 1561876. Full removal is tracked in bug 1487479. + // If we have eBlob, we are in an IDB SQLite schema upgrade where we don't + // care about a real 'MutableFile', but we just care of having a proper + // |mType| flag. + if (aFile.Type() == StructuredCloneFile::eBlob) { + aFile.MutateType(StructuredCloneFile::eMutableFile); - JS::Rooted obj(aCx, JS_NewPlainObject(aCx)); - if (NS_WARN_IF(!obj)) { + // Just make a dummy object. + JS::Rooted obj(aCx, JS_NewPlainObject(aCx)); + + if (NS_WARN_IF(!obj)) { + return false; + } + + aResult.set(obj); + return true; + } + + MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eMutableFile); + + if (!aFile.HasMutableFile() || !NS_IsMainThread()) { return false; } - aResult.set(obj); - return true; + aFile.MutableMutableFile().SetLazyData(aData.name, aData.type); + + return WrapAsJSObject(aCx, aFile.MutableMutableFile(), aResult); } - template static bool CreateAndWrapBlobOrFile(JSContext* aCx, IDBDatabase* aDatabase, const StructuredCloneFile& aFile, const BlobOrFileData& aData, @@ -209,10 +219,48 @@ class ValueDeserializationHelperBase { MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE || aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE || aData.tag == SCTAG_DOM_BLOB); - MOZ_ASSERT(aFile.Type() == StructuredCloneFileBase::eBlob); + MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eBlob); - const auto blob = ValueDeserializationHelper::GetBlob( - aCx, aDatabase, aFile); + const auto blob = [&aFile, aDatabase, aCx]() -> RefPtr { + if (aFile.HasBlob()) { + return aFile.BlobPtr(); + } + + // It can happen that this IDB is chrome code, so there is no parent, but + // still we want to set a correct parent for the new File object. + const auto global = [aDatabase, aCx]() -> nsCOMPtr { + if (NS_IsMainThread()) { + if (aDatabase && aDatabase->GetParentObject()) { + return aDatabase->GetParentObject(); + } + return xpc::CurrentNativeGlobal(aCx); + } + const WorkerPrivate* const workerPrivate = + GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + WorkerGlobalScope* const globalScope = workerPrivate->GlobalScope(); + MOZ_ASSERT(globalScope); + + return do_QueryObject(globalScope); + }(); + + MOZ_ASSERT(global); + + /* If we are creating an index, we do not have an mBlob but do have an + * FileInfo. Unlike other index or upgrade cases, we do need a + * real-looking Blob/File instance because the index's key path can + * reference their properties. Rather than create a fake-looking object, + * create a real Blob. */ + const nsCOMPtr file = aFile.FileInfo().GetFileForFileInfo(); + if (!file) { + return nullptr; + } + + const auto impl = MakeRefPtr(file); + impl->SetFileId(aFile.FileInfo().Id()); + return File::Create(global, impl); + }(); if (NS_WARN_IF(!blob)) { return false; } @@ -222,10 +270,6 @@ class ValueDeserializationHelperBase { INT64_MAX); MOZ_ASSERT(!blob->IsFile()); - // XXX The comment below is somewhat confusing, since it seems to imply - // that this branch is only executed when called from ActorsParent, but - // it's executed from both the parent and the child side code. - // ActorsParent sends here a kind of half blob and half file wrapped into // a DOM File object. DOM File and DOM Blob are a WebIDL wrapper around a // BlobImpl object. SetLazyData() has just changed the BlobImpl to be a @@ -251,27 +295,20 @@ class ValueDeserializationHelperBase { return WrapAsJSObject(aCx, file, aResult); } -}; -template <> -class ValueDeserializationHelper - : public ValueDeserializationHelperBase { - public: - static bool CreateAndWrapMutableFile(JSContext* aCx, - StructuredCloneFileParent& aFile, - const MutableFileData& aData, - JS::MutableHandle aResult) { + static bool CreateAndWrapWasmModule(JSContext* aCx, + const StructuredCloneFile& aFile, + const WasmModuleData& aData, + JS::MutableHandle aResult) { MOZ_ASSERT(aCx); - MOZ_ASSERT(aFile.Type() == StructuredCloneFileBase::eBlob); + MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eWasmBytecode); + MOZ_ASSERT(!aFile.HasBlob()); - // We are in an IDB SQLite schema upgrade where we don't care about a real - // 'MutableFile', but we just care of having a proper |mType| flag. + // Just create a plain object here, support for de-serialization of + // WebAssembly.Modules has been removed in bug 1561876. Full removal is + // tracked in bug 1487479. - aFile.MutateType(StructuredCloneFileBase::eMutableFile); - - // Just make a dummy object. JS::Rooted obj(aCx, JS_NewPlainObject(aCx)); - if (NS_WARN_IF(!obj)) { return false; } @@ -279,85 +316,10 @@ class ValueDeserializationHelper aResult.set(obj); return true; } - - static RefPtr GetBlob(JSContext* aCx, IDBDatabase* aDatabase, - const StructuredCloneFileParent& aFile) { - // This is chrome code, so there is no parent, but still we want to set a - // correct parent for the new File object. - const auto global = [aDatabase, aCx]() -> nsCOMPtr { - if (NS_IsMainThread()) { - if (aDatabase && aDatabase->GetParentObject()) { - return aDatabase->GetParentObject(); - } - return xpc::CurrentNativeGlobal(aCx); - } - const WorkerPrivate* const workerPrivate = - GetCurrentThreadWorkerPrivate(); - MOZ_ASSERT(workerPrivate); - - WorkerGlobalScope* const globalScope = workerPrivate->GlobalScope(); - MOZ_ASSERT(globalScope); - - return do_QueryObject(globalScope); - }(); - - MOZ_ASSERT(global); - - // We do not have an mBlob but do have an FileInfo. - // - // If we are creating an index, we do need a real-looking Blob/File instance - // because the index's key path can reference their properties. Rather than - // create a fake-looking object, create a real Blob. - // - // If we are in a schema upgrade, we don't strictly need that, but we do not - // need to optimize for that, and create it anyway. - const nsCOMPtr file = aFile.FileInfo().GetFileForFileInfo(); - if (!file) { - return nullptr; - } - - const auto impl = MakeRefPtr(file); - impl->SetFileId(aFile.FileInfo().Id()); - return File::Create(global, impl); - } -}; - -template <> -class ValueDeserializationHelper - : public ValueDeserializationHelperBase { - public: - static bool CreateAndWrapMutableFile(JSContext* aCx, - StructuredCloneFileChild& aFile, - const MutableFileData& aData, - JS::MutableHandle aResult) { - MOZ_ASSERT(aCx); - MOZ_ASSERT(aFile.Type() == StructuredCloneFileBase::eMutableFile); - - // If either MutableFile is disabled (via a pref) and we don't have a - // mutable file here, or we are on a DOM worker and MutableFile is not - // supported on workers, return false to indicate that. - if (!aFile.HasMutableFile() || !NS_IsMainThread()) { - return false; - } - - aFile.MutableMutableFile().SetLazyData(aData.name, aData.type); - - return WrapAsJSObject(aCx, aFile.MutableMutableFile(), aResult); - } - - static RefPtr GetBlob(JSContext* aCx, IDBDatabase* aDatabase, - const StructuredCloneFileChild& aFile) { - if (aFile.HasBlob()) { - return aFile.BlobPtr(); - } - - MOZ_CRASH("Expected a StructuredCloneFile with a Blob"); - } }; } // namespace -template JSObject* CommonStructuredCloneReadCallback( JSContext* aCx, JSStructuredCloneReader* aReader, const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData, @@ -372,9 +334,6 @@ JSObject* CommonStructuredCloneReadCallback( "You changed our structured clone tag values and just ate " "everyone's IndexedDB data. I hope you are happy."); - using StructuredCloneFile = - typename StructuredCloneReadInfo::StructuredCloneFile; - if (aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE || aTag == SCTAG_DOM_BLOB || aTag == SCTAG_DOM_FILE || aTag == SCTAG_DOM_MUTABLEFILE || aTag == SCTAG_DOM_WASM_MODULE) { @@ -396,10 +355,10 @@ JSObject* CommonStructuredCloneReadCallback( return nullptr; } - const auto& file = files[data.bytecodeIndex]; + const StructuredCloneFile& file = files[data.bytecodeIndex]; - if (NS_WARN_IF(!ValueDeserializationHelper:: - CreateAndWrapWasmModule(aCx, file, data, &result))) { + if (NS_WARN_IF(!ValueDeserializationHelper::CreateAndWrapWasmModule( + aCx, file, data, &result))) { return nullptr; } @@ -411,7 +370,7 @@ JSObject* CommonStructuredCloneReadCallback( return nullptr; } - auto& file = aCloneReadInfo->MutableFile(aData); + StructuredCloneFile& file = aCloneReadInfo->MutableFile(aData); if (aTag == SCTAG_DOM_MUTABLEFILE) { MutableFileData data; @@ -419,8 +378,8 @@ JSObject* CommonStructuredCloneReadCallback( return nullptr; } - if (NS_WARN_IF(!ValueDeserializationHelper:: - CreateAndWrapMutableFile(aCx, file, data, &result))) { + if (NS_WARN_IF(!ValueDeserializationHelper::CreateAndWrapMutableFile( + aCx, file, data, &result))) { return nullptr; } @@ -432,10 +391,8 @@ JSObject* CommonStructuredCloneReadCallback( return nullptr; } - if (NS_WARN_IF(!ValueDeserializationHelper< - StructuredCloneFile>::CreateAndWrapBlobOrFile(aCx, aDatabase, - file, data, - &result))) { + if (NS_WARN_IF(!ValueDeserializationHelper::CreateAndWrapBlobOrFile( + aCx, aDatabase, file, data, &result))) { return nullptr; } @@ -445,14 +402,4 @@ JSObject* CommonStructuredCloneReadCallback( return StructuredCloneHolder::ReadFullySerializableObjects(aCx, aReader, aTag); } - -template JSObject* CommonStructuredCloneReadCallback( - JSContext* aCx, JSStructuredCloneReader* aReader, - const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData, - StructuredCloneReadInfoChild* aCloneReadInfo, IDBDatabase* aDatabase); - -template JSObject* CommonStructuredCloneReadCallback( - JSContext* aCx, JSStructuredCloneReader* aReader, - const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData, - StructuredCloneReadInfoParent* aCloneReadInfo, IDBDatabase* aDatabase); } // namespace mozilla::dom::indexedDB diff --git a/dom/indexedDB/IndexedDatabase.h b/dom/indexedDB/IndexedDatabase.h index 7ecb07cd5728..ea532a0ae9b0 100644 --- a/dom/indexedDB/IndexedDatabase.h +++ b/dom/indexedDB/IndexedDatabase.h @@ -8,12 +8,11 @@ #define mozilla_dom_indexeddatabase_h__ #include "js/StructuredClone.h" -#include "mozilla/InitializedOnce.h" #include "mozilla/Variant.h" #include "nsCOMPtr.h" #include "nsTArray.h" +#include "InitializedOnce.h" #include "FileInfoFwd.h" -#include "SafeRefPtr.h" namespace mozilla { namespace dom { @@ -26,7 +25,7 @@ namespace indexedDB { class SerializedStructuredCloneReadInfo; -struct StructuredCloneFileBase { +struct StructuredCloneFile { enum FileType { eBlob, eMutableFile, @@ -36,36 +35,47 @@ struct StructuredCloneFileBase { eEndGuard }; - FileType Type() const { return mType; } - - protected: - explicit StructuredCloneFileBase(FileType aType) : mType{aType} {} - - FileType mType; -}; - -struct StructuredCloneFileChild : StructuredCloneFileBase { - StructuredCloneFileChild(const StructuredCloneFileChild&) = delete; - StructuredCloneFileChild& operator=(const StructuredCloneFileChild&) = delete; + StructuredCloneFile(const StructuredCloneFile&) = delete; + StructuredCloneFile& operator=(const StructuredCloneFile&) = delete; #ifdef NS_BUILD_REFCNT_LOGGING // In IndexedDatabaseInlines.h - StructuredCloneFileChild(StructuredCloneFileChild&&); + StructuredCloneFile(StructuredCloneFile&&); #else - StructuredCloneFileChild(StructuredCloneFileChild&&) = default; + StructuredCloneFile(StructuredCloneFile&&) = default; #endif - StructuredCloneFileChild& operator=(StructuredCloneFileChild&&) = delete; + StructuredCloneFile& operator=(StructuredCloneFile&&) = delete; // In IndexedDatabaseInlines.h - ~StructuredCloneFileChild(); + inline explicit StructuredCloneFile(FileType aType); // In IndexedDatabaseInlines.h - explicit StructuredCloneFileChild(FileType aType); + inline StructuredCloneFile(FileType aType, RefPtr aBlob); // In IndexedDatabaseInlines.h - StructuredCloneFileChild(FileType aType, RefPtr aBlob); + inline StructuredCloneFile(FileType aType, RefPtr aFileInfo); // In IndexedDatabaseInlines.h - explicit StructuredCloneFileChild(RefPtr aMutableFile); + inline explicit StructuredCloneFile(RefPtr aMutableFile); + + // In IndexedDatabaseInlines.h + ~StructuredCloneFile(); + + // In IndexedDatabaseInlines.h + inline bool operator==(const StructuredCloneFile& aOther) const; + + // XXX This is only needed for a schema upgrade (UpgradeSchemaFrom19_0To20_0). + // If support for older schemas is dropped, we can probably remove this method + // and make mType const. + void MutateType(FileType aNewType) { mType = aNewType; } + + FileType Type() const { return mType; } + + const indexedDB::FileInfo& FileInfo() const { + return *mContents->as>(); + } + + // In IndexedDatabaseInlines.h + RefPtr FileInfoPtr() const; const dom::Blob& Blob() const { return *mContents->as>(); } @@ -76,7 +86,7 @@ struct StructuredCloneFileChild : StructuredCloneFileBase { dom::Blob& MutableBlob() const { return *mContents->as>(); } // In IndexedDatabaseInlines.h - RefPtr BlobPtr() const; + inline RefPtr BlobPtr() const; bool HasBlob() const { return mContents->is>(); } @@ -94,58 +104,13 @@ struct StructuredCloneFileChild : StructuredCloneFileBase { private: InitializedOnce< - const Variant, RefPtr>> + const Variant, RefPtr, + RefPtr>> mContents; + FileType mType; }; -struct StructuredCloneFileParent : StructuredCloneFileBase { - StructuredCloneFileParent(const StructuredCloneFileParent&) = delete; - StructuredCloneFileParent& operator=(const StructuredCloneFileParent&) = - delete; -#ifdef NS_BUILD_REFCNT_LOGGING - // In IndexedDatabaseInlines.h - StructuredCloneFileParent(StructuredCloneFileParent&&); -#else - StructuredCloneFileParent(StructuredCloneFileParent&&) = default; -#endif - StructuredCloneFileParent& operator=(StructuredCloneFileParent&&) = delete; - - // In IndexedDatabaseInlines.h - StructuredCloneFileParent(FileType aType, SafeRefPtr aFileInfo); - - // In IndexedDatabaseInlines.h - ~StructuredCloneFileParent(); - - // XXX This is used for a schema upgrade hack in UpgradeSchemaFrom19_0To20_0. - // When this is eventually removed, this function can be removed, and mType - // can be declared const in the base class. - void MutateType(FileType aNewType) { mType = aNewType; } - - const indexedDB::FileInfo& FileInfo() const { return ***mContents; } - - // In IndexedDatabaseInlines.h - SafeRefPtr FileInfoPtr() const; - - private: - InitializedOnce>> mContents; -}; - -struct StructuredCloneReadInfoBase { - // In IndexedDatabaseInlines.h - explicit StructuredCloneReadInfoBase(JSStructuredCloneData&& aData) - : mData{std::move(aData)} {} - - const JSStructuredCloneData& Data() const { return mData; } - JSStructuredCloneData ReleaseData() { return std::move(mData); } - - private: - JSStructuredCloneData mData; -}; - -template -struct StructuredCloneReadInfo : StructuredCloneReadInfoBase { - using StructuredCloneFile = StructuredCloneFileT; - +struct StructuredCloneReadInfo { // In IndexedDatabaseInlines.h explicit StructuredCloneReadInfo(JS::StructuredCloneScope aScope); @@ -179,6 +144,9 @@ struct StructuredCloneReadInfo : StructuredCloneReadInfoBase { // In IndexedDatabaseInlines.h size_t Size() const; + const JSStructuredCloneData& Data() const { return mData; } + JSStructuredCloneData ReleaseData() { return std::move(mData); } + // XXX This is only needed for a schema upgrade (UpgradeSchemaFrom19_0To20_0). // If support for older schemas is dropped, we can probably remove this method // and make mFiles InitializedOnce. @@ -192,13 +160,13 @@ struct StructuredCloneReadInfo : StructuredCloneReadInfoBase { bool HasFiles() const { return !mFiles.IsEmpty(); } private: + JSStructuredCloneData mData; nsTArray mFiles; }; -struct StructuredCloneReadInfoChild - : StructuredCloneReadInfo { +struct StructuredCloneReadInfoChild : StructuredCloneReadInfo { inline StructuredCloneReadInfoChild(JSStructuredCloneData&& aData, - nsTArray aFiles, + nsTArray aFiles, IDBDatabase* aDatabase); IDBDatabase* Database() const { return mDatabase; } @@ -209,10 +177,9 @@ struct StructuredCloneReadInfoChild // This is only defined in the header file to satisfy the clang-plugin static // analysis, it could be placed in ActorsParent.cpp otherwise. -struct StructuredCloneReadInfoParent - : StructuredCloneReadInfo { +struct StructuredCloneReadInfoParent : StructuredCloneReadInfo { StructuredCloneReadInfoParent(JSStructuredCloneData&& aData, - nsTArray aFiles, + nsTArray aFiles, bool aHasPreprocessInfo) : StructuredCloneReadInfo{std::move(aData), std::move(aFiles)}, mHasPreprocessInfo{aHasPreprocessInfo} {} @@ -223,7 +190,6 @@ struct StructuredCloneReadInfoParent bool mHasPreprocessInfo; }; -template JSObject* CommonStructuredCloneReadCallback( JSContext* aCx, JSStructuredCloneReader* aReader, const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData, @@ -239,12 +205,7 @@ JSObject* StructuredCloneReadCallback( } // namespace dom } // namespace mozilla -DECLARE_USE_COPY_CONSTRUCTORS( - mozilla::dom::indexedDB::StructuredCloneReadInfo< - mozilla::dom::indexedDB::StructuredCloneFileChild>); -DECLARE_USE_COPY_CONSTRUCTORS( - mozilla::dom::indexedDB::StructuredCloneReadInfo< - mozilla::dom::indexedDB::StructuredCloneFileParent>); +DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::indexedDB::StructuredCloneReadInfo); DECLARE_USE_COPY_CONSTRUCTORS( mozilla::dom::indexedDB::StructuredCloneReadInfoChild); DECLARE_USE_COPY_CONSTRUCTORS( diff --git a/dom/indexedDB/IndexedDatabaseInlines.h b/dom/indexedDB/IndexedDatabaseInlines.h index f0435feaa072..9e28f253ede5 100644 --- a/dom/indexedDB/IndexedDatabaseInlines.h +++ b/dom/indexedDB/IndexedDatabaseInlines.h @@ -21,108 +21,88 @@ namespace mozilla { namespace dom { namespace indexedDB { -#ifdef NS_BUILD_REFCNT_LOGGING -inline StructuredCloneFileChild::StructuredCloneFileChild( - StructuredCloneFileChild&& aOther) - : StructuredCloneFileBase{std::move(aOther)}, - mContents{std::move(aOther.mContents)} { - MOZ_COUNT_CTOR(StructuredCloneFileChild); -} -#endif - -inline StructuredCloneFileChild::~StructuredCloneFileChild() { - MOZ_COUNT_DTOR(StructuredCloneFileChild); +inline StructuredCloneFile::StructuredCloneFile(FileType aType) + : mContents{Nothing()}, mType{aType} { + MOZ_COUNT_CTOR(StructuredCloneFile); } -inline StructuredCloneFileChild::StructuredCloneFileChild(FileType aType) - : StructuredCloneFileBase{aType}, mContents{Nothing()} { - MOZ_COUNT_CTOR(StructuredCloneFileChild); -} - -inline StructuredCloneFileChild::StructuredCloneFileChild( - FileType aType, RefPtr aBlob) - : StructuredCloneFileBase{aType}, mContents{std::move(aBlob)} { +inline StructuredCloneFile::StructuredCloneFile(FileType aType, + RefPtr aBlob) + : mContents{std::move(aBlob)}, mType{aType} { MOZ_ASSERT(eBlob == aType || eStructuredClone == aType); MOZ_ASSERT(mContents->as>()); - MOZ_COUNT_CTOR(StructuredCloneFileChild); + MOZ_COUNT_CTOR(StructuredCloneFile); } -inline StructuredCloneFileParent::StructuredCloneFileParent( - FileType aType, SafeRefPtr aFileInfo) - : StructuredCloneFileBase{aType}, mContents{Some(std::move(aFileInfo))} { - MOZ_ASSERT(**mContents); - MOZ_COUNT_CTOR(StructuredCloneFileParent); +inline StructuredCloneFile::StructuredCloneFile( + FileType aType, RefPtr aFileInfo) + : mContents{std::move(aFileInfo)}, mType{aType} { + MOZ_ASSERT(mContents->as>()); + MOZ_COUNT_CTOR(StructuredCloneFile); } -inline StructuredCloneFileChild::StructuredCloneFileChild( +inline StructuredCloneFile::StructuredCloneFile( RefPtr aMutableFile) - : StructuredCloneFileBase{eMutableFile}, - mContents{std::move(aMutableFile)} { + : mContents{std::move(aMutableFile)}, mType{eMutableFile} { MOZ_ASSERT(mContents->as>()); - MOZ_COUNT_CTOR(StructuredCloneFileChild); + MOZ_COUNT_CTOR(StructuredCloneFile); } #ifdef NS_BUILD_REFCNT_LOGGING -inline StructuredCloneFileParent::StructuredCloneFileParent( - StructuredCloneFileParent&& aOther) - : StructuredCloneFileBase{std::move(aOther)}, - mContents{std::move(aOther.mContents)} { - MOZ_COUNT_CTOR(StructuredCloneFileParent); +inline StructuredCloneFile::StructuredCloneFile(StructuredCloneFile&& aOther) + : mContents{std::move(aOther.mContents)}, mType{aOther.mType} { + MOZ_COUNT_CTOR(StructuredCloneFile); } #endif -inline StructuredCloneFileParent::~StructuredCloneFileParent() { - MOZ_COUNT_DTOR(StructuredCloneFileParent); +inline StructuredCloneFile::~StructuredCloneFile() { + MOZ_COUNT_DTOR(StructuredCloneFile); } -inline SafeRefPtr StructuredCloneFileParent::FileInfoPtr() - const { - return (*mContents)->clonePtr(); +inline RefPtr StructuredCloneFile::FileInfoPtr() const { + return mContents->as>(); } -inline RefPtr StructuredCloneFileChild::BlobPtr() const { +inline RefPtr StructuredCloneFile::BlobPtr() const { return mContents->as>(); } -template -inline StructuredCloneReadInfo::StructuredCloneReadInfo( +inline bool StructuredCloneFile::operator==( + const StructuredCloneFile& aOther) const { + return this->mType == aOther.mType && *this->mContents == *aOther.mContents; +} + +inline StructuredCloneReadInfo::StructuredCloneReadInfo( JS::StructuredCloneScope aScope) - : StructuredCloneReadInfoBase(JSStructuredCloneData{aScope}) { + : mData(aScope) { MOZ_COUNT_CTOR(StructuredCloneReadInfo); } -template -inline StructuredCloneReadInfo::StructuredCloneReadInfo() +inline StructuredCloneReadInfo::StructuredCloneReadInfo() : StructuredCloneReadInfo( JS::StructuredCloneScope::DifferentProcessForIndexedDB) {} -template -inline StructuredCloneReadInfo::StructuredCloneReadInfo( +inline StructuredCloneReadInfo::StructuredCloneReadInfo( JSStructuredCloneData&& aData, nsTArray aFiles) - : StructuredCloneReadInfoBase{std::move(aData)}, mFiles{std::move(aFiles)} { + : mData{std::move(aData)}, mFiles{std::move(aFiles)} { MOZ_COUNT_CTOR(StructuredCloneReadInfo); } #ifdef NS_BUILD_REFCNT_LOGGING -template -inline StructuredCloneReadInfo::StructuredCloneReadInfo( +inline StructuredCloneReadInfo::StructuredCloneReadInfo( StructuredCloneReadInfo&& aOther) noexcept - : StructuredCloneReadInfoBase{std::move(aOther)}, - mFiles{std::move(aOther.mFiles)} { + : mData{std::move(aOther.mData)}, mFiles{std::move(aOther.mFiles)} { MOZ_COUNT_CTOR(StructuredCloneReadInfo); } -template -inline StructuredCloneReadInfo< - StructuredCloneFile>::~StructuredCloneReadInfo() { +inline StructuredCloneReadInfo::~StructuredCloneReadInfo() { MOZ_COUNT_DTOR(StructuredCloneReadInfo); } #endif -template -inline size_t StructuredCloneReadInfo::Size() const { - size_t size = Data().Size(); +inline size_t StructuredCloneReadInfo::Size() const { + size_t size = mData.Size(); for (uint32_t i = 0, count = mFiles.Length(); i < count; ++i) { // We don't want to calculate the size of files and so on, because are @@ -134,7 +114,7 @@ inline size_t StructuredCloneReadInfo::Size() const { } inline StructuredCloneReadInfoChild::StructuredCloneReadInfoChild( - JSStructuredCloneData&& aData, nsTArray aFiles, + JSStructuredCloneData&& aData, nsTArray aFiles, IDBDatabase* aDatabase) : StructuredCloneReadInfo{std::move(aData), std::move(aFiles)}, mDatabase{aDatabase} {} @@ -172,7 +152,7 @@ JSObject* StructuredCloneReadCallback( }(); return CommonStructuredCloneReadCallback( aCx, aReader, aCloneDataPolicy, aTag, aData, - static_cast(aClosure), database); + static_cast(aClosure), database); } template diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp index 89f79d2f366e..fcdf65be1d78 100644 --- a/dom/indexedDB/IndexedDatabaseManager.cpp +++ b/dom/indexedDB/IndexedDatabaseManager.cpp @@ -60,10 +60,10 @@ using namespace mozilla::ipc; class FileManagerInfo { public: - MOZ_MUST_USE SafeRefPtr GetFileManager( + MOZ_MUST_USE RefPtr GetFileManager( PersistenceType aPersistenceType, const nsAString& aName) const; - void AddFileManager(SafeRefPtr aFileManager); + void AddFileManager(FileManager* aFileManager); bool HasFileManagers() const { AssertIsOnIOThread(); @@ -81,17 +81,16 @@ class FileManagerInfo { const nsAString& aName); private: - nsTArray >& GetArray( - PersistenceType aPersistenceType); + nsTArray >& GetArray(PersistenceType aPersistenceType); - const nsTArray >& GetImmutableArray( + const nsTArray >& GetImmutableArray( PersistenceType aPersistenceType) const { return const_cast(this)->GetArray(aPersistenceType); } - nsTArray > mPersistentStorageFileManagers; - nsTArray > mTemporaryStorageFileManagers; - nsTArray > mDefaultStorageFileManagers; + nsTArray > mPersistentStorageFileManagers; + nsTArray > mTemporaryStorageFileManagers; + nsTArray > mDefaultStorageFileManagers; }; } // namespace indexedDB @@ -680,7 +679,7 @@ void IndexedDatabaseManager::ClearBackgroundActor() { mBackgroundActor = nullptr; } -SafeRefPtr IndexedDatabaseManager::GetFileManager( +RefPtr IndexedDatabaseManager::GetFileManager( PersistenceType aPersistenceType, const nsACString& aOrigin, const nsAString& aDatabaseName) { AssertIsOnIOThread(); @@ -693,8 +692,7 @@ SafeRefPtr IndexedDatabaseManager::GetFileManager( return info->GetFileManager(aPersistenceType, aDatabaseName); } -void IndexedDatabaseManager::AddFileManager( - SafeRefPtr aFileManager) { +void IndexedDatabaseManager::AddFileManager(FileManager* aFileManager) { AssertIsOnIOThread(); NS_ASSERTION(aFileManager, "Null file manager!"); @@ -704,7 +702,7 @@ void IndexedDatabaseManager::AddFileManager( mFileManagerInfos.Put(aFileManager->Origin(), info); } - info->AddFileManager(std::move(aFileManager)); + info->AddFileManager(aFileManager); } void IndexedDatabaseManager::InvalidateAllFileManagers() { @@ -857,7 +855,7 @@ const nsCString& IndexedDatabaseManager::GetLocale() { return idbManager->mLocale; } -SafeRefPtr FileManagerInfo::GetFileManager( +RefPtr FileManagerInfo::GetFileManager( PersistenceType aPersistenceType, const nsAString& aName) const { AssertIsOnIOThread(); @@ -867,17 +865,17 @@ SafeRefPtr FileManagerInfo::GetFileManager( const auto foundIt = std::find_if(managers.cbegin(), end, DatabaseNameMatchPredicate(&aName)); - return foundIt != end ? foundIt->clonePtr() : nullptr; + return foundIt != end ? *foundIt : nullptr; } -void FileManagerInfo::AddFileManager(SafeRefPtr aFileManager) { +void FileManagerInfo::AddFileManager(FileManager* aFileManager) { AssertIsOnIOThread(); - nsTArray >& managers = GetArray(aFileManager->Type()); + nsTArray >& managers = GetArray(aFileManager->Type()); NS_ASSERTION(!managers.Contains(aFileManager), "Adding more than once?!"); - managers.AppendElement(std::move(aFileManager)); + managers.AppendElement(aFileManager); } void FileManagerInfo::InvalidateAllFileManagers() const { @@ -902,7 +900,7 @@ void FileManagerInfo::InvalidateAndRemoveFileManagers( PersistenceType aPersistenceType) { AssertIsOnIOThread(); - nsTArray >& managers = GetArray(aPersistenceType); + nsTArray >& managers = GetArray(aPersistenceType); for (uint32_t i = 0; i < managers.Length(); i++) { managers[i]->Invalidate(); @@ -926,7 +924,7 @@ void FileManagerInfo::InvalidateAndRemoveFileManager( } } -nsTArray >& FileManagerInfo::GetArray( +nsTArray >& FileManagerInfo::GetArray( PersistenceType aPersistenceType) { switch (aPersistenceType) { case PERSISTENCE_TYPE_PERSISTENT: diff --git a/dom/indexedDB/IndexedDatabaseManager.h b/dom/indexedDB/IndexedDatabaseManager.h index 09ffb2659fbe..615413644774 100644 --- a/dom/indexedDB/IndexedDatabaseManager.h +++ b/dom/indexedDB/IndexedDatabaseManager.h @@ -13,7 +13,6 @@ #include "mozilla/Mutex.h" #include "nsClassHashtable.h" #include "nsHashKeys.h" -#include "SafeRefPtr.h" namespace mozilla { @@ -104,11 +103,11 @@ class IndexedDatabaseManager final { void ClearBackgroundActor(); - MOZ_MUST_USE SafeRefPtr GetFileManager( + MOZ_MUST_USE RefPtr GetFileManager( PersistenceType aPersistenceType, const nsACString& aOrigin, const nsAString& aDatabaseName); - void AddFileManager(SafeRefPtr aFileManager); + void AddFileManager(FileManager* aFileManager); void InvalidateAllFileManagers(); diff --git a/dom/indexedDB/InitializedOnce.h b/dom/indexedDB/InitializedOnce.h new file mode 100644 index 000000000000..699947d349da --- /dev/null +++ b/dom/indexedDB/InitializedOnce.h @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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_indexeddb_initializedonce_h__ +#define mozilla_dom_indexeddb_initializedonce_h__ + +#include "mozilla/Assertions.h" +#include "mozilla/Maybe.h" + +#include + +// This file is not exported and is only meant to be included in IndexedDB +// source files. + +// TODO: However, it is meant to be moved to mfbt, and therefore already placed +// in the mozilla namespace. + +namespace mozilla { + +enum struct LazyInit { Allow, AllowResettable, ForbidResettable }; + +namespace ValueCheckPolicies { +template +struct AllowAnyValue { + constexpr static bool Check(const T& /*aValue*/) { return true; } +}; + +template +struct ConvertsToTrue { + constexpr static bool Check(const T& aValue) { + return static_cast(aValue); + } +}; +} // namespace ValueCheckPolicies + +// A kind of mozilla::Maybe that can only be initialized and cleared once. It +// cannot be re-initialized. This is a more stateful than a const Maybe in +// that it can be cleared, but much less stateful than a non-const Maybe +// which could be reinitialized multiple times. Can only be used with const T +// to ensure that the contents cannot be modified either. +// TODO: Make constructors constexpr when Maybe's constructors are constexpr +// (Bug 1601336). +template class ValueCheckPolicy = + ValueCheckPolicies::AllowAnyValue> +class InitializedOnce final { + static_assert(std::is_const_v); + + public: + template + explicit InitializedOnce( + std::enable_if_t* = nullptr) {} + + template + explicit InitializedOnce(Arg0&& aArg0, Args&&... aArgs) + : mMaybe{Some(std::remove_const_t{std::forward(aArg0), + std::forward(aArgs)...})} { + MOZ_ASSERT(ValueCheckPolicy::Check(*mMaybe)); + } + + InitializedOnce(const InitializedOnce&) = delete; + InitializedOnce(InitializedOnce&& aOther) : mMaybe{std::move(aOther.mMaybe)} { + static_assert(LazyInitVal == LazyInit::AllowResettable || + LazyInitVal == LazyInit::ForbidResettable); +#ifdef DEBUG + aOther.mWasReset = true; +#endif + } + InitializedOnce& operator=(const InitializedOnce&) = delete; + InitializedOnce& operator=(InitializedOnce&& aOther) { + static_assert(LazyInitVal == LazyInit::AllowResettable); + MOZ_ASSERT(!mWasReset); + MOZ_ASSERT(!mMaybe); + mMaybe.~Maybe>(); + new (&mMaybe) Maybe{std::move(aOther.mMaybe)}; +#ifdef DEBUG + aOther.mWasReset = true; +#endif + return *this; + } + + template + std::enable_if_t + init(Args&&... aArgs) { + MOZ_ASSERT(mMaybe.isNothing()); + MOZ_ASSERT(!mWasReset); + mMaybe.emplace(std::remove_const_t{std::forward(aArgs)...}); + MOZ_ASSERT(ValueCheckPolicy::Check(*mMaybe)); + } + + explicit operator bool() const { return isSome(); } + bool isSome() const { return mMaybe.isSome(); } + bool isNothing() const { return mMaybe.isNothing(); } + + T& operator*() const { return *mMaybe; } + T* operator->() const { return mMaybe.operator->(); } + + template + std::enable_if_t + reset() { + MOZ_ASSERT(mMaybe.isSome()); + maybeReset(); + } + + template + std::enable_if_t + maybeReset() { + mMaybe.reset(); +#ifdef DEBUG + mWasReset = true; +#endif + } + + template + std::enable_if_t + release() { + MOZ_ASSERT(mMaybe.isSome()); + auto res = std::move(mMaybe.ref()); + maybeReset(); + return res; + } + + private: + Maybe> mMaybe; +#ifdef DEBUG + bool mWasReset = false; +#endif +}; + +template +using InitializedOnceMustBeTrue = + InitializedOnce; + +} // namespace mozilla + +#endif diff --git a/dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh b/dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh index d2cce5bf0093..86605cafd82a 100644 --- a/dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh +++ b/dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh @@ -25,7 +25,7 @@ using struct mozilla::void_t using mozilla::dom::IDBCursor::Direction from "mozilla/dom/IDBCursor.h"; -using mozilla::dom::indexedDB::StructuredCloneFileBase::FileType +using mozilla::dom::indexedDB::StructuredCloneFile::FileType from "mozilla/dom/IndexedDatabase.h"; using class mozilla::dom::indexedDB::Key diff --git a/dom/indexedDB/SafeRefPtr.h b/dom/indexedDB/SafeRefPtr.h deleted file mode 100644 index ff1836a4fc22..000000000000 --- a/dom/indexedDB/SafeRefPtr.h +++ /dev/null @@ -1,185 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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_saferefptr_h__ -#define mozilla_saferefptr_h__ - -#include "mozilla/Maybe.h" -#include "mozilla/RefPtr.h" - -namespace mozilla { - -struct AcquireStrongRefFromRawPtr {}; - -// A restricted variant of mozilla::RefPtr, which prohibits some unsafe or -// unperformant misuses, in particular: -// * It is not implicitly convertible from a raw pointer. Unsafe acquisitions -// from a raw pointer must be made using the verbose -// AcquireStrongRefFromRawPtr. To create a new object on the heap, use -// MakeSafeRefPtr. -// * It does not implicitly decay to a raw pointer. get() must be called -// explicitly. -// * It is not copyable, but must be explicitly copied using clonePtr(). -// * Temporaries cannot be dereferenced using operator* or operator->. -template -class MOZ_IS_REFPTR SafeRefPtr { - template - friend class SafeRefPtr; - - RefPtr mRefPtr; - - public: - SafeRefPtr() = default; - - template >> - MOZ_IMPLICIT SafeRefPtr(SafeRefPtr&& aSrc) - : mRefPtr(std::move(aSrc.mRefPtr)) {} - - explicit SafeRefPtr(RefPtr&& aRefPtr) : mRefPtr(std::move(aRefPtr)) {} - - // To prevent implicit conversion of raw pointer to RefPtr and then - // calling the previous overload. - SafeRefPtr(T* const aRawPtr) = delete; - - SafeRefPtr(T* const aRawPtr, const AcquireStrongRefFromRawPtr&) - : mRefPtr(aRawPtr) {} - - MOZ_IMPLICIT SafeRefPtr(std::nullptr_t) {} - - // Prevent implicit copying, use clonePtr() instead. - SafeRefPtr(const SafeRefPtr&) = delete; - SafeRefPtr& operator=(const SafeRefPtr&) = delete; - - // Allow moving. - SafeRefPtr(SafeRefPtr&&) = default; - SafeRefPtr& operator=(SafeRefPtr&&) = default; - - typedef T element_type; - - explicit operator bool() const { return mRefPtr; } - bool operator!() const { return !mRefPtr; } - - T& operator*() const&& = delete; - - T& operator*() const& { return mRefPtr.operator*(); } - - T* operator->() const&& = delete; - - T* operator->() const& MOZ_NO_ADDREF_RELEASE_ON_RETURN { - return mRefPtr.operator->(); - } - - Maybe maybeDeref() const { - return mRefPtr ? SomeRef(*mRefPtr) : Nothing(); - } - - T* unsafeGetRawPtr() const { return mRefPtr.get(); } - - SafeRefPtr clonePtr() const { return SafeRefPtr{RefPtr{mRefPtr}}; } - - already_AddRefed forget() { return mRefPtr.forget(); } - - bool operator==(const SafeRefPtr& aOther) const { - return mRefPtr == aOther.mRefPtr; - } - - bool operator!=(const SafeRefPtr& aOther) const { - return mRefPtr != aOther.mRefPtr; - } - - template - friend RefPtr AsRefPtr(SafeRefPtr&& aSafeRefPtr); -}; - -template -SafeRefPtr(RefPtr &&)->SafeRefPtr; - -template -bool operator==(std::nullptr_t aLhs, const SafeRefPtr& aRhs) { - return !aRhs; -} - -template -bool operator!=(std::nullptr_t aLhs, const SafeRefPtr& aRhs) { - return static_cast(aRhs); -} - -template -bool operator==(const SafeRefPtr& aLhs, std::nullptr_t aRhs) { - return !aLhs; -} - -template -bool operator!=(const SafeRefPtr& aLhs, std::nullptr_t aRhs) { - return static_cast(aLhs); -} - -template > -bool operator==(T* const aLhs, const SafeRefPtr& aRhs) { - return aLhs == aRhs.unsafeGetRawPtr(); -} - -template > -bool operator!=(T* const aLhs, const SafeRefPtr& aRhs) { - return !(aLhs == aRhs); -} - -template > -bool operator==(const SafeRefPtr& aLhs, U* const aRhs) { - return aRhs == aLhs; -} - -template > -bool operator!=(const SafeRefPtr& aLhs, U* const aRhs) { - return aRhs != aLhs; -} - -template > -bool operator==(const Maybe aLhs, const SafeRefPtr& aRhs) { - return &aLhs.ref() == aRhs.unsafeGetRawPtr(); -} - -template > -bool operator!=(const Maybe aLhs, const SafeRefPtr& aRhs) { - return !(aLhs == aRhs); -} - -template > -bool operator==(const SafeRefPtr& aLhs, const Maybe aRhs) { - return aRhs == aLhs; -} - -template > -bool operator!=(const SafeRefPtr& aLhs, const Maybe aRhs) { - return aRhs != aLhs; -} - -template -RefPtr AsRefPtr(SafeRefPtr&& aSafeRefPtr) { - return std::move(aSafeRefPtr.mRefPtr); -} - -template -SafeRefPtr MakeSafeRefPtr(Args&&... aArgs) { - return SafeRefPtr{MakeRefPtr(std::forward(aArgs)...)}; -} - -template -void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, - const SafeRefPtr& aField, const char* aName, - uint32_t aFlags = 0) { - CycleCollectionNoteChild(aCallback, aField.unsafeGetRawPtr(), aName, aFlags); -} - -template -void ImplCycleCollectionUnlink(SafeRefPtr& aField) { - aField = nullptr; -} - -} // namespace mozilla - -#endif diff --git a/dom/indexedDB/SerializationHelpers.h b/dom/indexedDB/SerializationHelpers.h index 61df2f003bd8..3ae5ee205f05 100644 --- a/dom/indexedDB/SerializationHelpers.h +++ b/dom/indexedDB/SerializationHelpers.h @@ -17,11 +17,11 @@ namespace IPC { template <> -struct ParamTraits +struct ParamTraits : public ContiguousEnumSerializer< - mozilla::dom::indexedDB::StructuredCloneFileBase::FileType, - mozilla::dom::indexedDB::StructuredCloneFileBase::eBlob, - mozilla::dom::indexedDB::StructuredCloneFileBase::eEndGuard> {}; + mozilla::dom::indexedDB::StructuredCloneFile::FileType, + mozilla::dom::indexedDB::StructuredCloneFile::eBlob, + mozilla::dom::indexedDB::StructuredCloneFile::eEndGuard> {}; template <> struct ParamTraits { diff --git a/dom/indexedDB/moz.build b/dom/indexedDB/moz.build index 4906a4b44a97..3dd77d26b92e 100644 --- a/dom/indexedDB/moz.build +++ b/dom/indexedDB/moz.build @@ -41,7 +41,7 @@ EXPORTS.mozilla.dom += [ 'IDBTransaction.h', 'IndexedDatabase.h', 'IndexedDatabaseManager.h', - 'SafeRefPtr.h', + 'InitializedOnce.h', ] EXPORTS.mozilla.dom.indexedDB += [ diff --git a/dom/indexedDB/test/gtest/TestFileInfo.cpp b/dom/indexedDB/test/gtest/TestFileInfo.cpp index 44af31c1ccb1..31e5176ffe77 100644 --- a/dom/indexedDB/test/gtest/TestFileInfo.cpp +++ b/dom/indexedDB/test/gtest/TestFileInfo.cpp @@ -57,10 +57,8 @@ class TestFileManager final : public FileManagerBase { for (const auto id : kDBOnlyFileInfoIds) { // Copied from within FileManager::Init. - mFileInfos.Put( - id, new FileInfo(FileManagerGuard{}, - SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, id, - static_cast(1))); + mFileInfos.Put(id, new FileInfo(FileManagerGuard{}, this, id, + static_cast(1))); mLastFileId = std::max(id, mLastFileId); } @@ -108,7 +106,7 @@ TEST(DOM_IndexedDB_FileInfo, Create) int32_t memRefCnt, dbRefCnt; fileInfo->GetReferences(&memRefCnt, &dbRefCnt); - ASSERT_EQ(fileManager, &fileInfo->Manager()); + ASSERT_EQ(fileManager, fileInfo->Manager()); ASSERT_EQ(1, memRefCnt); ASSERT_EQ(0, dbRefCnt); @@ -133,7 +131,7 @@ TEST(DOM_IndexedDB_FileInfo, CreateWithInitialDBRefCnt) int32_t memRefCnt, dbRefCnt; fileInfo->GetReferences(&memRefCnt, &dbRefCnt); - ASSERT_EQ(fileManager, &fileInfo->Manager()); + ASSERT_EQ(fileManager, fileInfo->Manager()); ASSERT_EQ(1, memRefCnt); // we hold one in fileInfo ourselves ASSERT_EQ(1, dbRefCnt); @@ -153,7 +151,7 @@ TEST(DOM_IndexedDB_FileInfo, CreateWithInitialDBRefCnt_Invalidate) const auto fileManager = MakeRefPtr(&stats); fileManager->CreateDBOnlyFileInfos(); - auto fileInfos = nsTArray>{}; + auto fileInfos = nsTArray>{}; for (const auto id : TestFileManager::kDBOnlyFileInfoIds) { fileInfos.EmplaceBack(fileManager->GetFileInfo(id)); }