diff --git a/dom/cache/Context.cpp b/dom/cache/Context.cpp index af4dbe07bf18..d4fb7f9c86b7 100644 --- a/dom/cache/Context.cpp +++ b/dom/cache/Context.cpp @@ -16,8 +16,7 @@ #include "mozilla/dom/cache/ManagerId.h" #include "mozilla/dom/quota/Assertions.h" #include "mozilla/dom/quota/ClientDirectoryLock.h" -#include "mozilla/dom/quota/DirectoryLock.h" -#include "mozilla/dom/quota/DirectoryLockInlines.h" +#include "mozilla/dom/quota/ClientDirectoryLockHandle.h" #include "mozilla/dom/quota/PrincipalUtils.h" #include "mozilla/dom/quota/QuotaManager.h" #include "mozilla/dom/quota/ResultExtensions.h" @@ -57,6 +56,7 @@ namespace mozilla::dom::cache { using mozilla::dom::quota::AssertIsOnIOThread; using mozilla::dom::quota::ClientDirectoryLock; +using mozilla::dom::quota::ClientDirectoryLockHandle; using mozilla::dom::quota::PERSISTENCE_TYPE_DEFAULT; using mozilla::dom::quota::PersistenceType; using mozilla::dom::quota::QuotaManager; @@ -126,7 +126,7 @@ class Context::QuotaInitRunnable final : public nsIRunnable { Maybe MaybeDirectoryLockRef() const { NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable); - return ToMaybeRef(mDirectoryLock.get()); + return ToMaybeRef(mDirectoryLockHandle.get()); } nsresult Dispatch() { @@ -149,7 +149,7 @@ class Context::QuotaInitRunnable final : public nsIRunnable { mInitAction->CancelOnInitiatingThread(); } - void DirectoryLockAcquired(ClientDirectoryLock* aLock); + void DirectoryLockAcquired(ClientDirectoryLockHandle aLockHandle); void DirectoryLockFailed(); @@ -224,7 +224,7 @@ class Context::QuotaInitRunnable final : public nsIRunnable { nsresult mResult; Maybe mPrincipalInfo; Maybe mDirectoryMetadata; - RefPtr mDirectoryLock; + ClientDirectoryLockHandle mDirectoryLockHandle; RefPtr mCipherKeyManager; State mState; Atomic mCanceled; @@ -235,18 +235,18 @@ class Context::QuotaInitRunnable final : public nsIRunnable { }; void Context::QuotaInitRunnable::DirectoryLockAcquired( - ClientDirectoryLock* aLock) { + ClientDirectoryLockHandle aLockHandle) { NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable); - MOZ_DIAGNOSTIC_ASSERT(aLock); + MOZ_DIAGNOSTIC_ASSERT(aLockHandle); MOZ_DIAGNOSTIC_ASSERT(mState == STATE_WAIT_FOR_DIRECTORY_LOCK); - MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock); + MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLockHandle); - mDirectoryLock = aLock; + mDirectoryLockHandle = std::move(aLockHandle); - MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock->Id() >= 0); - mDirectoryMetadata->mDirectoryLockId = mDirectoryLock->Id(); + MOZ_DIAGNOSTIC_ASSERT(mDirectoryLockHandle->Id() >= 0); + mDirectoryMetadata->mDirectoryLockId = mDirectoryLockHandle->Id(); - if (mCanceled || mDirectoryLock->Invalidated()) { + if (mCanceled || mDirectoryLockHandle->Invalidated()) { Complete(NS_ERROR_ABORT); return; } @@ -267,7 +267,7 @@ void Context::QuotaInitRunnable::DirectoryLockAcquired( void Context::QuotaInitRunnable::DirectoryLockFailed() { NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable); MOZ_DIAGNOSTIC_ASSERT(mState == STATE_WAIT_FOR_DIRECTORY_LOCK); - MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock); + MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLockHandle); NS_WARNING("Failed to acquire a directory lock!"); @@ -386,10 +386,10 @@ Context::QuotaInitRunnable::Run() { ->Then( GetCurrentSerialEventTarget(), __func__, [self = RefPtr(this)]( - const quota::ClientDirectoryLockPromise::ResolveOrRejectValue& - aValue) { + QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { if (aValue.IsResolve()) { - self->DirectoryLockAcquired(aValue.ResolveValue()); + self->DirectoryLockAcquired(std::move(aValue.ResolveValue())); } else { self->DirectoryLockFailed(); } @@ -468,7 +468,7 @@ Context::QuotaInitRunnable::Run() { mInitAction->CompleteOnInitiatingThread(mResult); mContext->OnQuotaInit(mResult, mDirectoryMetadata, - std::move(mDirectoryLock), + std::move(mDirectoryLockHandle), std::move(mCipherKeyManager)); mState = STATE_COMPLETE; @@ -866,18 +866,18 @@ Maybe Context::MaybeDirectoryLockRef() const { if (mState == STATE_CONTEXT_PREINIT) { MOZ_DIAGNOSTIC_ASSERT(!mInitRunnable); - MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock); + MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLockHandle); return Nothing(); } if (mState == STATE_CONTEXT_INIT) { - MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock); + MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLockHandle); return mInitRunnable->MaybeDirectoryLockRef(); } - return ToMaybeRef(mDirectoryLock.get()); + return ToMaybeRef(mDirectoryLockHandle.get()); } CipherKeyManager& Context::MutableCipherKeyManagerRef() { @@ -963,7 +963,9 @@ Context::~Context() { mThreadsafeHandle->ContextDestroyed(*this); } - SafeDropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } // Note, this may set the mOrphanedData flag. mManager->RemoveContext(*this); @@ -1043,7 +1045,7 @@ void Context::DispatchAction(SafeRefPtr aAction, bool aDoomData) { void Context::OnQuotaInit( nsresult aRv, const Maybe& aDirectoryMetadata, - RefPtr aDirectoryLock, + ClientDirectoryLockHandle aDirectoryLockHandle, RefPtr aCipherKeyManager) { NS_ASSERT_OWNINGTHREAD(Context); @@ -1055,8 +1057,8 @@ void Context::OnQuotaInit( // Always save the directory lock to ensure QuotaManager does not shutdown // before the Context has gone away. - MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock); - mDirectoryLock = std::move(aDirectoryLock); + MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLockHandle); + mDirectoryLockHandle = std::move(aDirectoryLockHandle); MOZ_DIAGNOSTIC_ASSERT(!mCipherKeyManager); mCipherKeyManager = std::move(aCipherKeyManager); @@ -1085,8 +1087,8 @@ void Context::OnQuotaInit( // We could only assert below if quota initialization was a success which // is ensured by NS_FAILED(aRv) above MOZ_DIAGNOSTIC_ASSERT(mDirectoryMetadata); - MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock); - MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock->Invalidated()); + MOZ_DIAGNOSTIC_ASSERT(mDirectoryLockHandle); + MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLockHandle->Invalidated()); MOZ_DIAGNOSTIC_ASSERT_IF(mDirectoryMetadata->mIsPrivate, mCipherKeyManager); MOZ_DIAGNOSTIC_ASSERT(mState == STATE_CONTEXT_INIT); @@ -1180,15 +1182,16 @@ void Context::DoStringify(nsACString& aData) { aData.Append(kStringifyEndSet); }; - aData.Append( - kStringifyDelimiter + - // - "DirectoryLock:"_ns + IntToCString(static_cast(mDirectoryLock)) + - kStringifyDelimiter + - // - "NextContext:"_ns + IntToCString(static_cast(mNextContext)) + - // - kStringifyEndInstance); + aData.Append(kStringifyDelimiter + + // + "DirectoryLock:"_ns + + IntToCString(static_cast(mDirectoryLockHandle)) + + kStringifyDelimiter + + // + "NextContext:"_ns + + IntToCString(static_cast(mNextContext)) + + // + kStringifyEndInstance); if (mNextContext) { aData.Append(kStringifyDelimiter); diff --git a/dom/cache/Context.h b/dom/cache/Context.h index d1d15e8611f6..744626c9216e 100644 --- a/dom/cache/Context.h +++ b/dom/cache/Context.h @@ -10,6 +10,7 @@ #include "CacheCipherKeyManager.h" #include "mozilla/dom/SafeRefPtr.h" #include "mozilla/dom/cache/Types.h" +#include "mozilla/dom/quota/ClientDirectoryLockHandle.h" #include "mozilla/dom/quota/StringifyUtils.h" #include "nsCOMPtr.h" #include "nsISupportsImpl.h" @@ -66,6 +67,8 @@ class Manager; // via the code in ShutdownObserver.cpp. class Context final : public SafeRefCounted, public Stringifyable { using ClientDirectoryLock = mozilla::dom::quota::ClientDirectoryLock; + using ClientDirectoryLockHandle = + mozilla::dom::quota::ClientDirectoryLockHandle; public: // Define a class allowing other threads to hold the Context alive. This also @@ -184,7 +187,7 @@ class Context final : public SafeRefCounted, public Stringifyable { void DispatchAction(SafeRefPtr aAction, bool aDoomData = false); void OnQuotaInit(nsresult aRv, const Maybe& aDirectoryMetadata, - RefPtr aDirectoryLock, + ClientDirectoryLockHandle aDirectoryLockHandle, RefPtr aCipherKeyManager); SafeRefPtr CreateThreadsafeHandle(); @@ -214,7 +217,7 @@ class Context final : public SafeRefCounted, public Stringifyable { // when ThreadsafeHandle::AllowToClose() is called. SafeRefPtr mThreadsafeHandle; - RefPtr mDirectoryLock; + ClientDirectoryLockHandle mDirectoryLockHandle; RefPtr mCipherKeyManager; SafeRefPtr mNextContext; diff --git a/dom/fs/parent/datamodel/FileSystemDataManager.cpp b/dom/fs/parent/datamodel/FileSystemDataManager.cpp index 6f6c34a2e993..40731f965a65 100644 --- a/dom/fs/parent/datamodel/FileSystemDataManager.cpp +++ b/dom/fs/parent/datamodel/FileSystemDataManager.cpp @@ -27,8 +27,6 @@ #include "mozilla/dom/QMResult.h" #include "mozilla/dom/quota/ClientDirectoryLock.h" #include "mozilla/dom/quota/ClientImpl.h" -#include "mozilla/dom/quota/DirectoryLock.h" -#include "mozilla/dom/quota/DirectoryLockInlines.h" #include "mozilla/dom/quota/HashKeys.h" #include "mozilla/dom/quota/QuotaCommon.h" #include "mozilla/dom/quota/QuotaManager.h" @@ -321,7 +319,7 @@ void FileSystemDataManager::RegisterActor( NotNull aActor) { MOZ_ASSERT(!mBackgroundThreadAccessible.Access()->mActors.Contains(aActor)); MOZ_ASSERT(mState == State::Open); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); mBackgroundThreadAccessible.Access()->mActors.Insert(aActor); @@ -335,7 +333,7 @@ void FileSystemDataManager::RegisterActor( // directory lock if it has been invalidated and eventually notify the actor // about the abort. - if (mDirectoryLock->Invalidated()) { + if (mDirectoryLockHandle->Invalidated()) { aActor->RequestAllowToClose(); } } @@ -344,7 +342,7 @@ void FileSystemDataManager::UnregisterActor( NotNull aActor) { MOZ_ASSERT(mBackgroundThreadAccessible.Access()->mActors.Contains(aActor)); MOZ_ASSERT(mState == State::Open); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); mBackgroundThreadAccessible.Access()->mActors.Remove(aActor); @@ -616,28 +614,28 @@ RefPtr FileSystemDataManager::BeginOpen() { mQuotaManager ->OpenClientDirectory( {mOriginMetadata, mozilla::dom::quota::Client::FILESYSTEM}) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [self = RefPtr(this)]( - quota::ClientDirectoryLockPromise::ResolveOrRejectValue&& value) { - if (value.IsReject()) { - return BoolPromise::CreateAndReject(value.RejectValue(), - __func__); - } + ->Then(GetCurrentSerialEventTarget(), __func__, + [self = RefPtr(this)]( + quota::QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& value) { + if (value.IsReject()) { + return BoolPromise::CreateAndReject(value.RejectValue(), + __func__); + } - self->mDirectoryLock = std::move(value.ResolveValue()); + self->mDirectoryLockHandle = std::move(value.ResolveValue()); - MOZ_ASSERT(self->mDirectoryLock->Id() >= 0); - self->mDirectoryLockId = self->mDirectoryLock->Id(); + MOZ_ASSERT(self->mDirectoryLockHandle->Id() >= 0); + self->mDirectoryLockId = self->mDirectoryLockHandle->Id(); - if (self->mDirectoryLock->Invalidated()) { - return BoolPromise::CreateAndReject(NS_ERROR_ABORT, __func__); - } + if (self->mDirectoryLockHandle->Invalidated()) { + return BoolPromise::CreateAndReject(NS_ERROR_ABORT, __func__); + } - NotifyDatabaseWorkStarted(); + NotifyDatabaseWorkStarted(); - return BoolPromise::CreateAndResolve(true, __func__); - }) + return BoolPromise::CreateAndResolve(true, __func__); + }) ->Then( mQuotaManager->IOThread(), __func__, [self = RefPtr(this)]( @@ -758,7 +756,10 @@ RefPtr FileSystemDataManager::BeginClose() { ->Then(MutableBackgroundTargetPtr(), __func__, [self = RefPtr(this)]( const ShutdownPromise::ResolveOrRejectValue&) { - SafeDropDirectoryLock(self->mDirectoryLock); + { + auto destroyingDirectoryLockHandle = + std::move(self->mDirectoryLockHandle); + } RemoveFileSystemDataManager(self->mOriginMetadata.mOrigin); diff --git a/dom/fs/parent/datamodel/FileSystemDataManager.h b/dom/fs/parent/datamodel/FileSystemDataManager.h index 5a62d17c59ba..f03e3852656f 100644 --- a/dom/fs/parent/datamodel/FileSystemDataManager.h +++ b/dom/fs/parent/datamodel/FileSystemDataManager.h @@ -15,6 +15,7 @@ #include "mozilla/dom/FileSystemHelpers.h" #include "mozilla/dom/FileSystemTypes.h" #include "mozilla/dom/quota/CheckedUnsafePtr.h" +#include "mozilla/dom/quota/ClientDirectoryLockHandle.h" #include "mozilla/dom/quota/CommonMetadata.h" #include "mozilla/dom/quota/ForwardDecls.h" #include "nsCOMPtr.h" @@ -100,7 +101,7 @@ class FileSystemDataManager } Maybe MaybeDirectoryLockRef() const { - return ToMaybeRef(mDirectoryLock.get()); + return ToMaybeRef(mDirectoryLockHandle.get()); } FileSystemDatabaseManager* MutableDatabaseManagerPtr() const { @@ -178,7 +179,7 @@ class FileSystemDataManager const NotNull> mBackgroundTarget; const NotNull> mIOTarget; const NotNull> mIOTaskQueue; - RefPtr mDirectoryLock; + quota::ClientDirectoryLockHandle mDirectoryLockHandle; UniquePtr mDatabaseManager; MozPromiseHolder mOpenPromiseHolder; MozPromiseHolder mClosePromiseHolder; diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 2bfdfd61438b..04ea4e8f9088 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -123,6 +123,7 @@ #include "mozilla/dom/quota/CheckedUnsafePtr.h" #include "mozilla/dom/quota/Client.h" #include "mozilla/dom/quota/ClientDirectoryLock.h" +#include "mozilla/dom/quota/ClientDirectoryLockHandle.h" #include "mozilla/dom/quota/ClientImpl.h" #include "mozilla/dom/quota/ConditionalCompilation.h" #include "mozilla/dom/quota/DirectoryLock.h" @@ -2137,7 +2138,7 @@ class Database final SafeRefPtr mFactory; SafeRefPtr mMetadata; SafeRefPtr mFileManager; - RefPtr mDirectoryLock; + ClientDirectoryLockHandle mDirectoryLockHandle; nsTHashSet mTransactions; nsTHashMap> mMappedBlobs; RefPtr mConnection; @@ -2168,8 +2169,8 @@ class Database final const quota::OriginMetadata& aOriginMetadata, uint32_t aTelemetryId, SafeRefPtr aMetadata, SafeRefPtr aFileManager, - RefPtr aDirectoryLock, bool aInPrivateBrowsing, - const Maybe& aMaybeKey); + ClientDirectoryLockHandle aDirectoryLockHandle, + bool aInPrivateBrowsing, const Maybe& aMaybeKey); void AssertIsOnConnectionThread() const { #ifdef DEBUG @@ -2216,7 +2217,7 @@ class Database final Maybe MaybeDirectoryLockRef() const { AssertIsOnBackgroundThread(); - return ToMaybeRef(mDirectoryLock.get()); + return ToMaybeRef(mDirectoryLockHandle.get()); } int64_t DirectoryLockId() const { return mDirectoryLockId; } @@ -3036,7 +3037,7 @@ class FactoryOp Maybe mContentParentId; // Must be released on the main thread! - RefPtr mDirectoryLock; + ClientDirectoryLockHandle mDirectoryLockHandle; nsTArray>> mBlocking; nsTArray>> mBlockedOn; @@ -3152,7 +3153,7 @@ class FactoryOp NS_IMETHOD Run() final; - void DirectoryLockAcquired(ClientDirectoryLock* aLock); + void DirectoryLockAcquired(ClientDirectoryLockHandle aLockHandle); void DirectoryLockFailed(); @@ -4967,7 +4968,7 @@ class DeleteFilesRunnable final : public Runnable { nsCOMPtr mOwningEventTarget; SafeRefPtr mFileManager; - RefPtr mDirectoryLock; + ClientDirectoryLockHandle mDirectoryLockHandle; nsTArray mFileIds; State mState; DEBUGONLY(bool mDEBUGCountsAsPending = false); @@ -4999,7 +5000,7 @@ class DeleteFilesRunnable final : public Runnable { NS_DECL_NSIRUNNABLE - void DirectoryLockAcquired(ClientDirectoryLock* aLock); + void DirectoryLockAcquired(ClientDirectoryLockHandle aLockHandle); void DirectoryLockFailed(); }; @@ -9240,13 +9241,13 @@ Database::Database(SafeRefPtr aFactory, uint32_t aTelemetryId, SafeRefPtr aMetadata, SafeRefPtr aFileManager, - RefPtr aDirectoryLock, + ClientDirectoryLockHandle aDirectoryLockHandle, bool aInPrivateBrowsing, const Maybe& aMaybeKey) : mFactory(std::move(aFactory)), mMetadata(std::move(aMetadata)), mFileManager(std::move(aFileManager)), - mDirectoryLock(std::move(aDirectoryLock)), + mDirectoryLockHandle(std::move(aDirectoryLockHandle)), mPrincipalInfo(aPrincipalInfo), mOptionalContentParentId(aOptionalContentParentId), mOriginMetadata(aOriginMetadata), @@ -9267,9 +9268,9 @@ Database::Database(SafeRefPtr aFactory, MOZ_ASSERT(mMetadata); MOZ_ASSERT(mFileManager); - MOZ_ASSERT(mDirectoryLock); - MOZ_ASSERT(mDirectoryLock->Id() >= 0); - mDirectoryLockId = mDirectoryLock->Id(); + MOZ_ASSERT(mDirectoryLockHandle); + MOZ_ASSERT(mDirectoryLockHandle->Id() >= 0); + mDirectoryLockId = mDirectoryLockHandle->Id(); } template @@ -9334,7 +9335,7 @@ nsresult Database::EnsureConnection() { bool Database::RegisterTransaction(TransactionBase& aTransaction) { AssertIsOnBackgroundThread(); MOZ_ASSERT(!mTransactions.Contains(&aTransaction)); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(!mInvalidated); MOZ_ASSERT(!mClosed); @@ -9389,7 +9390,7 @@ void Database::Stringify(nsACString& aResult) const { constexpr auto kQuotaGenericDelimiterString = "|"_ns; aResult.Append( - "DirectoryLock:"_ns + IntToCString(!!mDirectoryLock) + + "DirectoryLock:"_ns + IntToCString(!!mDirectoryLockHandle) + kQuotaGenericDelimiterString + // "Transactions:"_ns + IntToCString(mTransactions.Count()) + @@ -9511,7 +9512,7 @@ bool Database::CloseInternal() { void Database::MaybeCloseConnection() { AssertIsOnBackgroundThread(); - if (!mTransactions.Count() && IsClosed() && mDirectoryLock) { + if (!mTransactions.Count() && IsClosed() && mDirectoryLockHandle) { nsCOMPtr callback = NewRunnableMethod("dom::indexedDB::Database::ConnectionClosedCallback", this, &Database::ConnectionClosedCallback); @@ -9527,7 +9528,9 @@ void Database::ConnectionClosedCallback() { MOZ_ASSERT(mClosed); MOZ_ASSERT(!mTransactions.Count()); - DropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } CleanupMetadata(); @@ -12878,10 +12881,10 @@ void DeleteFilesRunnable::Open() { {mFileManager->OriginMetadata(), quota::Client::IDB}) ->Then( GetCurrentSerialEventTarget(), __func__, - [self = RefPtr(this)]( - const ClientDirectoryLockPromise::ResolveOrRejectValue& aValue) { + [self = RefPtr(this)](QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { if (aValue.IsResolve()) { - self->DirectoryLockAcquired(aValue.ResolveValue()); + self->DirectoryLockAcquired(std::move(aValue.ResolveValue())); } else { self->DirectoryLockFailed(); } @@ -12917,7 +12920,9 @@ void DeleteFilesRunnable::UnblockOpen() { AssertIsOnBackgroundThread(); MOZ_ASSERT(mState == State_UnblockingOpen); - SafeDropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } MOZ_ASSERT(mDEBUGCountsAsPending); sPendingRunnables--; @@ -12949,12 +12954,13 @@ DeleteFilesRunnable::Run() { return NS_OK; } -void DeleteFilesRunnable::DirectoryLockAcquired(ClientDirectoryLock* aLock) { +void DeleteFilesRunnable::DirectoryLockAcquired( + ClientDirectoryLockHandle aLockHandle) { AssertIsOnBackgroundThread(); MOZ_ASSERT(mState == State_DirectoryOpenPending); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); - mDirectoryLock = aLock; + mDirectoryLockHandle = std::move(aLockHandle); QuotaManager* const quotaManager = QuotaManager::Get(); MOZ_ASSERT(quotaManager); @@ -12970,7 +12976,7 @@ void DeleteFilesRunnable::DirectoryLockAcquired(ClientDirectoryLock* aLock) { void DeleteFilesRunnable::DirectoryLockFailed() { AssertIsOnBackgroundThread(); MOZ_ASSERT(mState == State_DirectoryOpenPending); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); Finish(); } @@ -14757,7 +14763,7 @@ nsresult FactoryOp::Open() { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::Initial); MOZ_ASSERT(mOriginMetadata.mOrigin.IsEmpty()); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || IsActorDestroyed()) { @@ -14849,10 +14855,10 @@ nsresult FactoryOp::Open() { quotaManager->OpenClientDirectory({mOriginMetadata, Client::IDB}) ->Then( GetCurrentSerialEventTarget(), __func__, - [self = RefPtr(this)]( - const ClientDirectoryLockPromise::ResolveOrRejectValue& aValue) { + [self = RefPtr(this)](QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { if (aValue.IsResolve()) { - self->DirectoryLockAcquired(aValue.ResolveValue()); + self->DirectoryLockAcquired(std::move(aValue.ResolveValue())); } else { self->DirectoryLockFailed(); } @@ -14864,7 +14870,7 @@ nsresult FactoryOp::Open() { nsresult FactoryOp::DirectoryOpen() { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::DirectoryOpenPending); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); if (mDatabaseName.isNothing()) { QuotaManager* const quotaManager = QuotaManager::Get(); @@ -14890,7 +14896,7 @@ nsresult FactoryOp::DirectoryOpen() { nsresult FactoryOp::DirectoryWorkDone() { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::DirectoryWorkDone); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(gFactoryOps); // See if this FactoryOp needs to wait. @@ -15142,16 +15148,16 @@ FactoryOp::Run() { return NS_OK; } -void FactoryOp::DirectoryLockAcquired(ClientDirectoryLock* aLock) { +void FactoryOp::DirectoryLockAcquired(ClientDirectoryLockHandle aLockHandle) { AssertIsOnOwningThread(); - MOZ_ASSERT(aLock); + MOZ_ASSERT(aLockHandle); MOZ_ASSERT(mState == State::DirectoryOpenPending); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); - mDirectoryLock = aLock; + mDirectoryLockHandle = std::move(aLockHandle); - MOZ_ASSERT(mDirectoryLock->Id() >= 0); - mDirectoryLockId = mDirectoryLock->Id(); + MOZ_ASSERT(mDirectoryLockHandle->Id() >= 0); + mDirectoryLockId = mDirectoryLockHandle->Id(); auto cleanupAndReturn = [self = RefPtr(this)](const nsresult rv) { self->SetFailureCodeIfUnset(rv); @@ -15163,7 +15169,7 @@ void FactoryOp::DirectoryLockAcquired(ClientDirectoryLock* aLock) { MOZ_ALWAYS_SUCCEEDS(self->Run()); }; - if (mDirectoryLock->Invalidated()) { + if (mDirectoryLockHandle->Invalidated()) { return cleanupAndReturn(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR); } @@ -15173,7 +15179,7 @@ void FactoryOp::DirectoryLockAcquired(ClientDirectoryLock* aLock) { void FactoryOp::DirectoryLockFailed() { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::DirectoryOpenPending); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); if (!HasFailed()) { IDB_REPORT_INTERNAL_ERR(); @@ -15999,7 +16005,7 @@ void OpenDatabaseOp::SendResults() { } if (mDatabase) { - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); if (HasFailed()) { mDatabase->Invalidate(); @@ -16009,7 +16015,7 @@ void OpenDatabaseOp::SendResults() { mDatabase = nullptr; CleanupMetadata(); - } else if (mDirectoryLock) { + } else if (mDirectoryLockHandle) { // ConnectionClosedCallback will call CleanupMetadata(). nsCOMPtr callback = NewRunnableMethod( "dom::indexedDB::OpenDatabaseOp::ConnectionClosedCallback", this, @@ -16028,9 +16034,11 @@ void OpenDatabaseOp::SendResults() { void OpenDatabaseOp::ConnectionClosedCallback() { AssertIsOnOwningThread(); MOZ_ASSERT(HasFailed()); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); - DropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } CleanupMetadata(); } @@ -16066,7 +16074,7 @@ void OpenDatabaseOp::EnsureDatabaseActor() { MOZ_RELEASE_ASSERT(mInPrivateBrowsing == maybeKey.isSome()); - const bool directoryLockInvalidated = mDirectoryLock->Invalidated(); + const bool directoryLockInvalidated = mDirectoryLockHandle->Invalidated(); // XXX Shouldn't Manager() return already_AddRefed when // PBackgroundIDBFactoryParent is declared refcounted? @@ -16075,7 +16083,7 @@ void OpenDatabaseOp::EnsureDatabaseActor() { AcquireStrongRefFromRawPtr{}}, mCommonParams.principalInfo(), mContentParentId, mOriginMetadata, mTelemetryId, mMetadata.clonePtr(), mFileManager.clonePtr(), - std::move(mDirectoryLock), mInPrivateBrowsing, maybeKey); + std::move(mDirectoryLockHandle), mInPrivateBrowsing, maybeKey); if (info) { info->mLiveDatabases.AppendElement( @@ -16627,7 +16635,9 @@ void DeleteDatabaseOp::SendResults() { response); } - SafeDropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } CleanupMetadata(); @@ -16987,7 +16997,9 @@ void GetDatabasesOp::SendResults() { mResolver(mDatabaseMetadataArray); } - SafeDropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } CleanupMetadata(); diff --git a/dom/localstorage/ActorsParent.cpp b/dom/localstorage/ActorsParent.cpp index 8247e2f909bd..e8e9a0515fb3 100644 --- a/dom/localstorage/ActorsParent.cpp +++ b/dom/localstorage/ActorsParent.cpp @@ -76,9 +76,8 @@ #include "mozilla/dom/quota/CheckedUnsafePtr.h" #include "mozilla/dom/quota/Client.h" #include "mozilla/dom/quota/ClientDirectoryLock.h" +#include "mozilla/dom/quota/ClientDirectoryLockHandle.h" #include "mozilla/dom/quota/ClientImpl.h" -#include "mozilla/dom/quota/DirectoryLock.h" -#include "mozilla/dom/quota/DirectoryLockInlines.h" #include "mozilla/dom/quota/FirstInitializationAttemptsImpl.h" #include "mozilla/dom/quota/HashKeys.h" #include "mozilla/dom/quota/OriginScope.h" @@ -1470,7 +1469,7 @@ class ConnectionThread final { */ class Datastore final : public SupportsCheckedUnsafePtr> { - RefPtr mDirectoryLock; + ClientDirectoryLockHandle mDirectoryLockHandle; RefPtr mConnection; RefPtr mQuotaObject; nsCOMPtr mCompleteCallback; @@ -1525,7 +1524,7 @@ class Datastore final // Created by PrepareDatastoreOp. Datastore(const OriginMetadata& aOriginMetadata, uint32_t aPrivateBrowsingId, int64_t aUsage, int64_t aSizeOfKeys, int64_t aSizeOfItems, - RefPtr&& aDirectoryLock, + ClientDirectoryLockHandle&& aDirectoryLockHandle, RefPtr&& aConnection, RefPtr&& aQuotaObject, nsTHashMap& aValues, @@ -1534,7 +1533,7 @@ class Datastore final Maybe MaybeDirectoryLockRef() const { AssertIsOnBackgroundThread(); - return ToMaybeRef(mDirectoryLock.get()); + return ToMaybeRef(mDirectoryLockHandle.get()); } const nsCString& Origin() const { return mOriginMetadata.mOrigin; } @@ -2285,8 +2284,8 @@ class PrepareDatastoreOp mozilla::glean::TimerId mProcessingTimerId; RefPtr mPendingDirectoryLock; - RefPtr mDirectoryLock; - RefPtr mExtraDirectoryLock; + ClientDirectoryLockHandle mDirectoryLockHandle; + ClientDirectoryLockHandle mExtraDirectoryLockHandle; RefPtr mConnection; RefPtr mDatastore; UniquePtr mArchivedOriginScope; @@ -2325,11 +2324,11 @@ class PrepareDatastoreOp Maybe MaybeDirectoryLockRef() const { AssertIsOnBackgroundThread(); - if (mDirectoryLock) { - return SomeRef(*mDirectoryLock); + if (mDirectoryLockHandle) { + return SomeRef(*mDirectoryLockHandle); } - if (mExtraDirectoryLock) { - return SomeRef(*mExtraDirectoryLock); + if (mExtraDirectoryLockHandle) { + return SomeRef(*mExtraDirectoryLockHandle); } return Nothing(); } @@ -2413,7 +2412,7 @@ class PrepareDatastoreOp // IPDL overrides. void ActorDestroy(ActorDestroyReason aWhy) override; - void DirectoryLockAcquired(ClientDirectoryLock* aLock); + void DirectoryLockAcquired(ClientDirectoryLockHandle aLockHandle); void DirectoryLockFailed(); }; @@ -4443,12 +4442,12 @@ void ConnectionThread::Shutdown() { Datastore::Datastore(const OriginMetadata& aOriginMetadata, uint32_t aPrivateBrowsingId, int64_t aUsage, int64_t aSizeOfKeys, int64_t aSizeOfItems, - RefPtr&& aDirectoryLock, + ClientDirectoryLockHandle&& aDirectoryLockHandle, RefPtr&& aConnection, RefPtr&& aQuotaObject, nsTHashMap& aValues, nsTArray&& aOrderedItems) - : mDirectoryLock(std::move(aDirectoryLock)), + : mDirectoryLockHandle(std::move(aDirectoryLockHandle)), mConnection(std::move(aConnection)), mQuotaObject(std::move(aQuotaObject)), mOrderedItems(std::move(aOrderedItems)), @@ -4477,7 +4476,7 @@ void Datastore::Close() { MOZ_ASSERT(!mPrepareDatastoreOps.Count()); MOZ_ASSERT(!mPreparedDatastores.Count()); MOZ_ASSERT(!mDatabases.Count()); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); mClosed = true; @@ -4498,7 +4497,9 @@ void Datastore::Close() { // There's no connection, so it's safe to release the directory lock and // unregister itself from the hashtable. - DropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } CleanupMetadata(); } @@ -4518,7 +4519,7 @@ void Datastore::NoteLivePrepareDatastoreOp( AssertIsOnBackgroundThread(); MOZ_ASSERT(aPrepareDatastoreOp); MOZ_ASSERT(!mPrepareDatastoreOps.Contains(aPrepareDatastoreOp)); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(!mClosed); mPrepareDatastoreOps.Insert(aPrepareDatastoreOp); @@ -4529,7 +4530,7 @@ void Datastore::NoteFinishedPrepareDatastoreOp( AssertIsOnBackgroundThread(); MOZ_ASSERT(aPrepareDatastoreOp); MOZ_ASSERT(mPrepareDatastoreOps.Contains(aPrepareDatastoreOp)); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(!mClosed); mPrepareDatastoreOps.Remove(aPrepareDatastoreOp); @@ -4543,7 +4544,7 @@ void Datastore::NoteFinishedPrepareDatastoreOp( void Datastore::NoteLivePrivateDatastore() { AssertIsOnBackgroundThread(); MOZ_ASSERT(!mHasLivePrivateDatastore); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(!mClosed); mHasLivePrivateDatastore = true; @@ -4552,7 +4553,7 @@ void Datastore::NoteLivePrivateDatastore() { void Datastore::NoteFinishedPrivateDatastore() { AssertIsOnBackgroundThread(); MOZ_ASSERT(mHasLivePrivateDatastore); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(!mClosed); mHasLivePrivateDatastore = false; @@ -4568,7 +4569,7 @@ void Datastore::NoteLivePreparedDatastore( AssertIsOnBackgroundThread(); MOZ_ASSERT(aPreparedDatastore); MOZ_ASSERT(!mPreparedDatastores.Contains(aPreparedDatastore)); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(!mClosed); mPreparedDatastores.Insert(aPreparedDatastore); @@ -4579,7 +4580,7 @@ void Datastore::NoteFinishedPreparedDatastore( AssertIsOnBackgroundThread(); MOZ_ASSERT(aPreparedDatastore); MOZ_ASSERT(mPreparedDatastores.Contains(aPreparedDatastore)); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(!mClosed); mPreparedDatastores.Remove(aPreparedDatastore); @@ -4606,7 +4607,7 @@ void Datastore::NoteLiveDatabase(Database* aDatabase) { AssertIsOnBackgroundThread(); MOZ_ASSERT(aDatabase); MOZ_ASSERT(!mDatabases.Contains(aDatabase)); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(!mClosed); mDatabases.Insert(aDatabase); @@ -4619,7 +4620,7 @@ void Datastore::NoteFinishedDatabase(Database* aDatabase) { MOZ_ASSERT(aDatabase); MOZ_ASSERT(mDatabases.Contains(aDatabase)); MOZ_ASSERT(!mActiveDatabases.Contains(aDatabase)); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(!mClosed); mDatabases.Remove(aDatabase); @@ -5170,7 +5171,7 @@ void Datastore::Stringify(nsACString& aResult) const { AssertIsOnBackgroundThread(); aResult.AppendLiteral("DirectoryLock:"); - aResult.AppendInt(!!mDirectoryLock); + aResult.AppendInt(!!mDirectoryLockHandle); aResult.Append(kQuotaGenericDelimiter); aResult.AppendLiteral("Connection:"); @@ -5247,7 +5248,7 @@ void Datastore::MaybeClose() { void Datastore::ConnectionClosedCallback() { AssertIsOnBackgroundThread(); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(mConnection); MOZ_ASSERT(mQuotaObject); MOZ_ASSERT(mClosed); @@ -5274,7 +5275,9 @@ void Datastore::ConnectionClosedCallback() { // Now it's safe to release the directory lock and unregister itself from // the hashtable. - DropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } CleanupMetadata(); @@ -6633,8 +6636,8 @@ PrepareDatastoreOp::PrepareDatastoreOp( } PrepareDatastoreOp::~PrepareDatastoreOp() { - MOZ_DIAGNOSTIC_ASSERT(!mDirectoryLock); - MOZ_DIAGNOSTIC_ASSERT(!mExtraDirectoryLock); + MOZ_DIAGNOSTIC_ASSERT(mDirectoryLockHandle.IsInert()); + MOZ_DIAGNOSTIC_ASSERT(mExtraDirectoryLockHandle.IsInert()); MOZ_ASSERT_IF(MayProceedOnNonOwningThread(), mState == State::Initial || mState == State::Completed); MOZ_ASSERT(!mLoadDataOp); @@ -6793,7 +6796,7 @@ nsresult PrepareDatastoreOp::OpenDirectory() { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::Nesting); MOZ_ASSERT(mNestedState == NestedState::OpenDirectory); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || !MayProceed()) { @@ -6853,12 +6856,12 @@ nsresult PrepareDatastoreOp::OpenDirectory() { /* aCreateIfNonExistent */ false, SomeRef(mPendingDirectoryLock)) ->Then( GetCurrentSerialEventTarget(), __func__, - [self = RefPtr(this)]( - const ClientDirectoryLockPromise::ResolveOrRejectValue& aValue) { + [self = RefPtr(this)](QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { self->mPendingDirectoryLock = nullptr; if (aValue.IsResolve()) { - self->DirectoryLockAcquired(aValue.ResolveValue()); + self->DirectoryLockAcquired(std::move(aValue.ResolveValue())); } else { self->DirectoryLockFailed(); } @@ -6968,7 +6971,7 @@ nsresult PrepareDatastoreOp::BeginDatastorePreparationInternal() { if ((mDatastore = GetDatastore(Origin()))) { MOZ_ASSERT(!mDatastore->IsClosed()); - mExtraDirectoryLock = std::move(mDirectoryLock); + mExtraDirectoryLockHandle = std::move(mDirectoryLockHandle); mDatastore->NoteLivePrepareDatastoreOp(this); @@ -7542,12 +7545,12 @@ void PrepareDatastoreOp::GetResponse(LSRequestResponse& aResponse) { } } - MOZ_ASSERT(mDirectoryLock); - MOZ_ASSERT_IF(mDirectoryLock->Invalidated(), mInvalidated); + MOZ_ASSERT(mDirectoryLockHandle); + MOZ_ASSERT_IF(mDirectoryLockHandle->Invalidated(), mInvalidated); mDatastore = new Datastore( mOriginMetadata, mPrivateBrowsingId, mUsage, mSizeOfKeys, mSizeOfItems, - std::move(mDirectoryLock), std::move(mConnection), + std::move(mDirectoryLockHandle), std::move(mConnection), std::move(quotaObject), mValues, std::move(mOrderedItems)); mDatastore->NoteLivePrepareDatastoreOp(this); @@ -7628,7 +7631,7 @@ void PrepareDatastoreOp::Cleanup() { AssertIsOnOwningThread(); if (mDatastore) { - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); MOZ_ASSERT(!mConnection); if (NS_FAILED(ResultCode())) { @@ -7663,15 +7666,17 @@ void PrepareDatastoreOp::Cleanup() { mDatastore = nullptr; - SafeDropDirectoryLock(mExtraDirectoryLock); + { + auto extraDirectoryLockHandle = std::move(mExtraDirectoryLockHandle); + } CleanupMetadata(); } else if (mConnection) { // If we have a connection then the operation must have failed and there // must be a directory lock too. MOZ_ASSERT(NS_FAILED(ResultCode())); - MOZ_ASSERT(mDirectoryLock); - MOZ_ASSERT(!mExtraDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); + MOZ_ASSERT(!mExtraDirectoryLockHandle); // We must close the connection on the connection thread before releasing // it on this thread. The directory lock can't be released either. @@ -7684,14 +7689,16 @@ void PrepareDatastoreOp::Cleanup() { // If we don't have a connection, but we do have a directory lock then the // operation must have failed or we were preloading a datastore and there // was no physical database on disk. - MOZ_ASSERT_IF(mDirectoryLock, + MOZ_ASSERT_IF(mDirectoryLockHandle, NS_FAILED(ResultCode()) || mDatabaseNotAvailable); - MOZ_ASSERT(!mExtraDirectoryLock); + MOZ_ASSERT(!mExtraDirectoryLockHandle); // There's no connection, so it's safe to release the directory lock and // unregister itself from the array. - SafeDropDirectoryLock(mDirectoryLock); + { + auto destroyingDdirectoryLockHandle = std::move(mDirectoryLockHandle); + } CleanupMetadata(); } @@ -7700,12 +7707,14 @@ void PrepareDatastoreOp::Cleanup() { void PrepareDatastoreOp::ConnectionClosedCallback() { AssertIsOnOwningThread(); MOZ_ASSERT(NS_FAILED(ResultCode())); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(mConnection); mConnection = nullptr; - DropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } CleanupMetadata(); } @@ -7747,18 +7756,19 @@ void PrepareDatastoreOp::ActorDestroy(ActorDestroyReason aWhy) { } } -void PrepareDatastoreOp::DirectoryLockAcquired(ClientDirectoryLock* aLock) { +void PrepareDatastoreOp::DirectoryLockAcquired( + ClientDirectoryLockHandle aLockHandle) { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::Nesting); MOZ_ASSERT(mNestedState == NestedState::DirectoryOpenPending); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); mPendingDirectoryLock = nullptr; - mDirectoryLock = aLock; + mDirectoryLockHandle = std::move(aLockHandle); if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || - !MayProceed() || mDirectoryLock->Invalidated()) { + !MayProceed() || mDirectoryLockHandle->Invalidated()) { MaybeSetFailureCode(NS_ERROR_ABORT); FinishNesting(); @@ -7777,7 +7787,7 @@ void PrepareDatastoreOp::DirectoryLockFailed() { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::Nesting); MOZ_ASSERT(mNestedState == NestedState::DirectoryOpenPending); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); mPendingDirectoryLock = nullptr; diff --git a/dom/quota/ActorsParent.cpp b/dom/quota/ActorsParent.cpp index db546feff2a5..f27c48e04fb6 100644 --- a/dom/quota/ActorsParent.cpp +++ b/dom/quota/ActorsParent.cpp @@ -94,6 +94,7 @@ #include "mozilla/dom/quota/CheckedUnsafePtr.h" #include "mozilla/dom/quota/Client.h" #include "mozilla/dom/quota/ClientDirectoryLock.h" +#include "mozilla/dom/quota/ClientDirectoryLockHandle.h" #include "mozilla/dom/quota/Config.h" #include "mozilla/dom/quota/Constants.h" #include "mozilla/dom/quota/DirectoryLockInlines.h" @@ -5486,7 +5487,8 @@ RefPtr QuotaManager::OpenStorageDirectory( }); } -RefPtr QuotaManager::OpenClientDirectory( +RefPtr +QuotaManager::OpenClientDirectory( const ClientMetadata& aClientMetadata, bool aInitializeOrigin, bool aCreateIfNonExistent, Maybe&> aPendingDirectoryLockOut) { @@ -5554,7 +5556,7 @@ RefPtr QuotaManager::OpenClientDirectory( aPendingDirectoryLockOut.ref() = clientDirectoryLock; } - RefPtr promise = + RefPtr promise = BoolPromise::All(GetCurrentSerialEventTarget(), promises) ->Then( GetCurrentSerialEventTarget(), __func__, @@ -5595,28 +5597,33 @@ RefPtr QuotaManager::OpenClientDirectory( aClientMetadata, aCreateIfNonExistent, std::move(originDirectoryLock)); })) - ->Then(GetCurrentSerialEventTarget(), __func__, - [clientDirectoryLock = std::move(clientDirectoryLock)]( - const BoolPromise::ResolveOrRejectValue& aValue) mutable { - if (aValue.IsReject()) { - DropDirectoryLockIfNotDropped(clientDirectoryLock); + ->Then( + GetCurrentSerialEventTarget(), __func__, + [clientDirectoryLock = std::move(clientDirectoryLock)]( + const BoolPromise::ResolveOrRejectValue& aValue) mutable { + if (aValue.IsReject()) { + DropDirectoryLockIfNotDropped(clientDirectoryLock); - return ClientDirectoryLockPromise::CreateAndReject( - aValue.RejectValue(), __func__); - } + return ClientDirectoryLockHandlePromise::CreateAndReject( + aValue.RejectValue(), __func__); + } - QM_TRY(ArtificialFailure(nsIQuotaArtificialFailure:: - CATEGORY_OPEN_CLIENT_DIRECTORY), - [&clientDirectoryLock](nsresult rv) { - DropDirectoryLockIfNotDropped(clientDirectoryLock); + QM_TRY( + ArtificialFailure(nsIQuotaArtificialFailure:: + CATEGORY_OPEN_CLIENT_DIRECTORY), + [&clientDirectoryLock](nsresult rv) { + DropDirectoryLockIfNotDropped(clientDirectoryLock); - return ClientDirectoryLockPromise::CreateAndReject( - rv, __func__); - }); + return ClientDirectoryLockHandlePromise::CreateAndReject( + rv, __func__); + }); - return ClientDirectoryLockPromise::CreateAndResolve( - std::move(clientDirectoryLock), __func__); - }); + auto clientDirectoryLockHandle = + ClientDirectoryLockHandle(std::move(clientDirectoryLock)); + + return ClientDirectoryLockHandlePromise::CreateAndResolve( + std::move(clientDirectoryLockHandle), __func__); + }); NotifyClientDirectoryOpeningStarted(*this); diff --git a/dom/quota/ClientDirectoryLockHandle.h b/dom/quota/ClientDirectoryLockHandle.h index 0a9f1f2f52cd..07e5051be4b1 100644 --- a/dom/quota/ClientDirectoryLockHandle.h +++ b/dom/quota/ClientDirectoryLockHandle.h @@ -20,15 +20,14 @@ class ClientDirectoryLock; * @brief RAII-style wrapper for managing a ClientDirectoryLock. * * ClientDirectoryLockHandle is a RAII-style wrapper that manages a - * ClientDirectoryLock. It is designed to ensure that the associated directory - * lock remains acquired while the handle is in scope and is automatically - * released when destroyed. + * ClientDirectoryLock created by QuotaManager::OpenClientDirectory. * - * This class will be used by OpenClientDirectory to manage the lifetime of - * directory locks in a safer and clearer way. + * This class ensures that the associated directory lock remains acquired + * while the handle is in scope and automatically drops it when destroyed. * * ## Usage: - * - Intended for use with QuotaManager::OpenClientDirectory. + * - See QuotaManager::OpenClientDirectory for details on obtaining a + * ClientDirectoryLockHandle. * - The handle should be retained for as long as access to the directory is * needed. * diff --git a/dom/quota/QuotaManager.h b/dom/quota/QuotaManager.h index 33b33b9a6c5b..616b5d6ad0c2 100644 --- a/dom/quota/QuotaManager.h +++ b/dom/quota/QuotaManager.h @@ -73,6 +73,7 @@ class ClearRequestBase; class ClientStorageScope; class ClientUsageArray; class ClientDirectoryLock; +class ClientDirectoryLockHandle; class DirectoryLockImpl; class GroupInfo; class GroupInfoPair; @@ -121,6 +122,9 @@ class QuotaManager final : public BackgroundThreadObject { class Observer; public: + using ClientDirectoryLockHandlePromise = + MozPromise; + QuotaManager(const nsAString& aBasePath, const nsAString& aStorageName); NS_INLINE_DECL_REFCOUNTING(QuotaManager) @@ -303,23 +307,29 @@ class QuotaManager final : public BackgroundThreadObject { // This is the main entry point into the QuotaManager API. // Any storage API implementation (quota client) that participates in - // centralized quota and storage handling should call this method to get - // a directory lock which will protect client's files from being deleted - // while they are still in use. - // After a lock is acquired, client is notified by resolving the returned - // promise. If the lock couldn't be acquired, client is notified by rejecting - // the returned promise. The returned lock could have been invalidated by a - // clear operation so consumers are supposed to check that and eventually - // release the lock as soon as possible (this is usually not needed for short - // lived operations). - // A lock is a reference counted object and at the time the returned promise - // is resolved, there are no longer other strong references except the one - // held by the resolve value itself. So it's up to client to add a new - // reference in order to keep the lock alive. - // Unlocking is simply done by calling lock object's Drop method. Unlocking - // must be always done explicitly before the lock object is destroyed (when - // the last strong reference is removed). - RefPtr OpenClientDirectory( + // centralized quota and storage handling should call this method to obtain + // a directory lock, ensuring the client’s files are protected from deletion + // while in use. + // + // After a lock is acquired, the client is notified by resolving the returned + // promise. If the lock couldn't be acquired, the promise is rejected. + // + // The returned lock is encapsulated in ClientDirectoryLockHandle, which + // manages ownership and automatically drops the lock when destroyed. Clients + // should retain ownership of the handle for as long as the lock is needed. + // + // The lock may still be invalidated by a clear operation, so consumers + // should check its validity and release it as soon as it is no longer + // required. + // + // Internally, QuotaManager may perform various initialization steps before + // resolving the promise. This can include storage, temporary storage, group + // and origin initialization. + // + // Optionally, an output parameter (aPendingDirectoryLockOut) can be provided + // to receive a reference to the ClientDirectoryLock before wrapping it in + // ClientDirectoryLockHandle. This allows tracking pending locks separately. + RefPtr OpenClientDirectory( const ClientMetadata& aClientMetadata, bool aInitializeOrigins = true, bool aCreateIfNonExistent = true, Maybe&> aPendingDirectoryLockOut = Nothing()); diff --git a/dom/quota/test/gtest/QuotaManagerDependencyFixture.h b/dom/quota/test/gtest/QuotaManagerDependencyFixture.h index 881050cbdf36..fc5598a92c61 100644 --- a/dom/quota/test/gtest/QuotaManagerDependencyFixture.h +++ b/dom/quota/test/gtest/QuotaManagerDependencyFixture.h @@ -11,6 +11,7 @@ #include "mozilla/MozPromise.h" #include "mozilla/SpinEventLoopUntil.h" #include "mozilla/dom/quota/ClientDirectoryLock.h" +#include "mozilla/dom/quota/ClientDirectoryLockHandle.h" #include "mozilla/dom/quota/DirectoryLock.h" #include "mozilla/dom/quota/DirectoryLockInlines.h" #include "mozilla/dom/quota/ForwardDecls.h" @@ -156,7 +157,7 @@ class QuotaManagerDependencyFixture : public testing::Test { Task&& aTask) { PerformOnBackgroundThread([clientMetadata = aClientMetadata, task = std::forward(aTask)]() mutable { - RefPtr directoryLock; + ClientDirectoryLockHandle directoryLockHandle; QuotaManager* quotaManager = QuotaManager::Get(); ASSERT_TRUE(quotaManager); @@ -166,9 +167,9 @@ class QuotaManagerDependencyFixture : public testing::Test { quotaManager->OpenClientDirectory(clientMetadata) ->Then( GetCurrentSerialEventTarget(), __func__, - [&directoryLock, - &done](RefPtr aResolveValue) { - directoryLock = std::move(aResolveValue); + [&directoryLockHandle, + &done](ClientDirectoryLockHandle&& aResolveValue) { + directoryLockHandle = std::move(aResolveValue); done = true; }, @@ -180,11 +181,13 @@ class QuotaManagerDependencyFixture : public testing::Test { SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; }); - ASSERT_TRUE(directoryLock); + ASSERT_TRUE(directoryLockHandle); - PerformOnIOThread(std::move(task), directoryLock->Id()); + PerformOnIOThread(std::move(task), directoryLockHandle->Id()); - DropDirectoryLock(directoryLock); + { + auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); + } }); } diff --git a/dom/quota/test/gtest/TestFileOutputStream.cpp b/dom/quota/test/gtest/TestFileOutputStream.cpp index f3d2dbb5c238..8069fdb399e4 100644 --- a/dom/quota/test/gtest/TestFileOutputStream.cpp +++ b/dom/quota/test/gtest/TestFileOutputStream.cpp @@ -6,6 +6,7 @@ #include "mozilla/dom/quota/Client.h" #include "mozilla/dom/quota/ClientDirectoryLock.h" +#include "mozilla/dom/quota/ClientDirectoryLockHandle.h" #include "mozilla/dom/quota/CommonMetadata.h" #include "mozilla/dom/quota/FileStreams.h" #include "mozilla/dom/quota/QuotaManager.h" @@ -181,7 +182,7 @@ TEST_F(TestFileOutputStream, extendFileStreamWithSetEOF) { ASSERT_TRUE(0 == avail); }; - RefPtr directoryLock; + ClientDirectoryLockHandle directoryLockHandle; QuotaManager* quotaManager = QuotaManager::Get(); ASSERT_TRUE(quotaManager); @@ -193,8 +194,9 @@ TEST_F(TestFileOutputStream, extendFileStreamWithSetEOF) { {GetOutputStreamTestOriginMetadata(), Client::SDB}) ->Then( GetCurrentSerialEventTarget(), __func__, - [&directoryLock, &done](RefPtr aResolveValue) { - directoryLock = std::move(aResolveValue); + [&directoryLockHandle, + &done](ClientDirectoryLockHandle&& aResolveValue) { + directoryLockHandle = std::move(aResolveValue); done = true; }, @@ -206,11 +208,13 @@ TEST_F(TestFileOutputStream, extendFileStreamWithSetEOF) { SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; }); - ASSERT_TRUE(directoryLock); + ASSERT_TRUE(directoryLockHandle); PerformOnIOThread(std::move(ioTask)); - DropDirectoryLock(directoryLock); + { + auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); + } }; PerformOnBackgroundThread(std::move(backgroundTask)); diff --git a/dom/quota/test/gtest/TestQuotaManager.cpp b/dom/quota/test/gtest/TestQuotaManager.cpp index be2ce6aac2dc..4f220d17fef7 100644 --- a/dom/quota/test/gtest/TestQuotaManager.cpp +++ b/dom/quota/test/gtest/TestQuotaManager.cpp @@ -8,6 +8,7 @@ #include "mozilla/BasePrincipal.h" #include "mozilla/ipc/PBackgroundSharedTypes.h" #include "mozilla/dom/quota/ClientDirectoryLock.h" +#include "mozilla/dom/quota/ClientDirectoryLockHandle.h" #include "mozilla/dom/quota/DirectoryLock.h" #include "mozilla/dom/quota/DirectoryLockInlines.h" #include "mozilla/dom/quota/OriginScope.h" @@ -423,27 +424,27 @@ TEST_F(TestQuotaManager, OpenClientDirectory_OngoingWithScheduledShutdown) { QuotaManager* quotaManager = QuotaManager::Get(); ASSERT_TRUE(quotaManager); - RefPtr directoryLock; + ClientDirectoryLockHandle directoryLockHandle; nsTArray> promises; promises.AppendElement( quotaManager->OpenClientDirectory(GetTestClientMetadata()) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [&directoryLock]( - ClientDirectoryLockPromise::ResolveOrRejectValue&& aValue) { - if (aValue.IsReject()) { - return BoolPromise::CreateAndReject(aValue.RejectValue(), - __func__); - } + ->Then(GetCurrentSerialEventTarget(), __func__, + [&directoryLockHandle]( + QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { + if (aValue.IsReject()) { + return BoolPromise::CreateAndReject(aValue.RejectValue(), + __func__); + } - [&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }(); + [&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }(); - directoryLock = std::move(aValue.ResolveValue()); + directoryLockHandle = std::move(aValue.ResolveValue()); - return BoolPromise::CreateAndResolve(true, __func__); - }) + return BoolPromise::CreateAndResolve(true, __func__); + }) ->Then(quotaManager->IOThread(), __func__, [](const BoolPromise::ResolveOrRejectValue& aValue) { if (aValue.IsReject()) { @@ -462,9 +463,12 @@ TEST_F(TestQuotaManager, OpenClientDirectory_OngoingWithScheduledShutdown) { return BoolPromise::CreateAndResolve(true, __func__); }) ->Then(GetCurrentSerialEventTarget(), __func__, - [&directoryLock]( + [&directoryLockHandle]( const BoolPromise::ResolveOrRejectValue& aValue) { - DropDirectoryLock(directoryLock); + { + auto destroyingDirectoryLockHandle = + std::move(directoryLockHandle); + } if (aValue.IsReject()) { return BoolPromise::CreateAndReject(aValue.RejectValue(), @@ -476,20 +480,24 @@ TEST_F(TestQuotaManager, OpenClientDirectory_OngoingWithScheduledShutdown) { promises.AppendElement(quotaManager->ShutdownStorage()); promises.AppendElement( quotaManager->OpenClientDirectory(GetTestClientMetadata()) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [](ClientDirectoryLockPromise::ResolveOrRejectValue&& aValue) { - if (aValue.IsReject()) { - return BoolPromise::CreateAndReject(aValue.RejectValue(), - __func__); - } + ->Then(GetCurrentSerialEventTarget(), __func__, + [](QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { + if (aValue.IsReject()) { + return BoolPromise::CreateAndReject(aValue.RejectValue(), + __func__); + } - RefPtr directoryLock = - std::move(aValue.ResolveValue()); - DropDirectoryLock(directoryLock); + ClientDirectoryLockHandle directoryLockHandle = + std::move(aValue.ResolveValue()); - return BoolPromise::CreateAndResolve(true, __func__); - })); + { + auto destroyingDirectoryLockHandle = + std::move(directoryLockHandle); + } + + return BoolPromise::CreateAndResolve(true, __func__); + })); { auto value = @@ -527,40 +535,48 @@ TEST_F(TestQuotaManager, promises.AppendElement( quotaManager->OpenClientDirectory(GetTestClientMetadata()) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [&directoryLock]( - ClientDirectoryLockPromise::ResolveOrRejectValue&& aValue) { - DropDirectoryLock(directoryLock); + ->Then(GetCurrentSerialEventTarget(), __func__, + [&directoryLock]( + QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { + DropDirectoryLock(directoryLock); - if (aValue.IsReject()) { - return BoolPromise::CreateAndReject(aValue.RejectValue(), - __func__); - } + if (aValue.IsReject()) { + return BoolPromise::CreateAndReject(aValue.RejectValue(), + __func__); + } - RefPtr directoryLock = - std::move(aValue.ResolveValue()); - DropDirectoryLock(directoryLock); + ClientDirectoryLockHandle directoryLockHandle = + std::move(aValue.ResolveValue()); - return BoolPromise::CreateAndResolve(true, __func__); - })); + { + auto destroyingDirectoryLockHandle = + std::move(directoryLockHandle); + } + + return BoolPromise::CreateAndResolve(true, __func__); + })); promises.AppendElement(directoryLock->Acquire()); promises.AppendElement( quotaManager->OpenClientDirectory(GetTestClientMetadata()) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [](ClientDirectoryLockPromise::ResolveOrRejectValue&& aValue) { - if (aValue.IsReject()) { - return BoolPromise::CreateAndReject(aValue.RejectValue(), - __func__); - } + ->Then(GetCurrentSerialEventTarget(), __func__, + [](QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { + if (aValue.IsReject()) { + return BoolPromise::CreateAndReject(aValue.RejectValue(), + __func__); + } - RefPtr directoryLock = - std::move(aValue.ResolveValue()); - DropDirectoryLock(directoryLock); + ClientDirectoryLockHandle directoryLockHandle = + std::move(aValue.ResolveValue()); - return BoolPromise::CreateAndResolve(true, __func__); - })); + { + auto destroyingDirectoryLockHandle = + std::move(directoryLockHandle); + } + + return BoolPromise::CreateAndResolve(true, __func__); + })); { auto value = @@ -592,9 +608,12 @@ TEST_F(TestQuotaManager, OpenClientDirectory_Finished) { Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); ASSERT_TRUE(value.IsResolve()); - RefPtr directoryLock = + ClientDirectoryLockHandle directoryLockHandle = std::move(value.ResolveValue()); - DropDirectoryLock(directoryLock); + + { + auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); + } ASSERT_TRUE(quotaManager->IsStorageInitialized()); } @@ -604,9 +623,12 @@ TEST_F(TestQuotaManager, OpenClientDirectory_Finished) { Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); ASSERT_TRUE(value.IsResolve()); - RefPtr directoryLock = + ClientDirectoryLockHandle directoryLockHandle = std::move(value.ResolveValue()); - DropDirectoryLock(directoryLock); + + { + auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); + } ASSERT_TRUE(quotaManager->IsStorageInitialized()); } @@ -633,9 +655,12 @@ TEST_F(TestQuotaManager, OpenClientDirectory_FinishedWithScheduledShutdown) { Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); ASSERT_TRUE(value.IsResolve()); - RefPtr directoryLock = + ClientDirectoryLockHandle directoryLockHandle = std::move(value.ResolveValue()); - DropDirectoryLock(directoryLock); + + { + auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); + } ASSERT_TRUE(quotaManager->IsStorageInitialized()); } @@ -645,20 +670,24 @@ TEST_F(TestQuotaManager, OpenClientDirectory_FinishedWithScheduledShutdown) { promises.AppendElement(quotaManager->ShutdownStorage()); promises.AppendElement( quotaManager->OpenClientDirectory(GetTestClientMetadata()) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [](ClientDirectoryLockPromise::ResolveOrRejectValue&& aValue) { - if (aValue.IsReject()) { - return BoolPromise::CreateAndReject(aValue.RejectValue(), - __func__); - } + ->Then(GetCurrentSerialEventTarget(), __func__, + [](QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { + if (aValue.IsReject()) { + return BoolPromise::CreateAndReject(aValue.RejectValue(), + __func__); + } - RefPtr directoryLock = - std::move(aValue.ResolveValue()); - DropDirectoryLock(directoryLock); + ClientDirectoryLockHandle directoryLockHandle = + std::move(aValue.ResolveValue()); - return BoolPromise::CreateAndResolve(true, __func__); - })); + { + auto destroyingDirectoryLockHandle = + std::move(directoryLockHandle); + } + + return BoolPromise::CreateAndResolve(true, __func__); + })); { auto value = @@ -692,9 +721,12 @@ TEST_F(TestQuotaManager, Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); ASSERT_TRUE(value.IsResolve()); - RefPtr directoryLock = + ClientDirectoryLockHandle directoryLockHandle = std::move(value.ResolveValue()); - DropDirectoryLock(directoryLock); + + { + auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); + } ASSERT_TRUE(quotaManager->IsStorageInitialized()); } @@ -713,9 +745,12 @@ TEST_F(TestQuotaManager, Await(quotaManager->OpenClientDirectory(GetTestClientMetadata())); ASSERT_TRUE(value.IsResolve()); - RefPtr directoryLock = + ClientDirectoryLockHandle directoryLockHandle = std::move(value.ResolveValue()); - DropDirectoryLock(directoryLock); + + { + auto destroyingDirectoryLockHandle = std::move(directoryLockHandle); + } ASSERT_TRUE(quotaManager->IsStorageInitialized()); } @@ -737,26 +772,26 @@ TEST_F(TestQuotaManager, OpenClientDirectory_InitializeOrigin) { QuotaManager* quotaManager = QuotaManager::Get(); ASSERT_TRUE(quotaManager); - RefPtr directoryLock; + ClientDirectoryLockHandle directoryLockHandle; RefPtr promise = quotaManager ->OpenClientDirectory(GetTestClientMetadata(), aInitializeOrigin) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [&directoryLock]( - ClientDirectoryLockPromise::ResolveOrRejectValue&& aValue) { - if (aValue.IsReject()) { - return BoolPromise::CreateAndReject(aValue.RejectValue(), - __func__); - } + ->Then(GetCurrentSerialEventTarget(), __func__, + [&directoryLockHandle]( + QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { + if (aValue.IsReject()) { + return BoolPromise::CreateAndReject(aValue.RejectValue(), + __func__); + } - [&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }(); + [&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }(); - directoryLock = std::move(aValue.ResolveValue()); + directoryLockHandle = std::move(aValue.ResolveValue()); - return BoolPromise::CreateAndResolve(true, __func__); - }) + return BoolPromise::CreateAndResolve(true, __func__); + }) ->Then(quotaManager->IOThread(), __func__, [aInitializeOrigin]( const BoolPromise::ResolveOrRejectValue& aValue) { @@ -778,9 +813,12 @@ TEST_F(TestQuotaManager, OpenClientDirectory_InitializeOrigin) { return BoolPromise::CreateAndResolve(true, __func__); }) ->Then(GetCurrentSerialEventTarget(), __func__, - [&directoryLock]( + [&directoryLockHandle]( const BoolPromise::ResolveOrRejectValue& aValue) { - DropDirectoryLock(directoryLock); + { + auto destroyingDirectoryLockHandle = + std::move(directoryLockHandle); + } if (aValue.IsReject()) { return BoolPromise::CreateAndReject(aValue.RejectValue(), diff --git a/dom/simpledb/ActorsParent.cpp b/dom/simpledb/ActorsParent.cpp index 9e7127f6f790..9af0fb38f0bd 100644 --- a/dom/simpledb/ActorsParent.cpp +++ b/dom/simpledb/ActorsParent.cpp @@ -36,9 +36,8 @@ #include "mozilla/dom/ipc/IdType.h" #include "mozilla/dom/quota/Client.h" #include "mozilla/dom/quota/ClientDirectoryLock.h" +#include "mozilla/dom/quota/ClientDirectoryLockHandle.h" #include "mozilla/dom/quota/ClientImpl.h" -#include "mozilla/dom/quota/DirectoryLock.h" -#include "mozilla/dom/quota/DirectoryLockInlines.h" #include "mozilla/dom/quota/FileStreams.h" #include "mozilla/dom/quota/PrincipalUtils.h" #include "mozilla/dom/quota/QuotaCommon.h" @@ -117,7 +116,7 @@ class StreamHelper final : public Runnable { }; class Connection final : public PBackgroundSDBConnectionParent { - RefPtr mDirectoryLock; + ClientDirectoryLockHandle mDirectoryLockHandle; nsCOMPtr mFileRandomAccessStream; const PrincipalInfo mPrincipalInfo; nsCString mOrigin; @@ -138,7 +137,7 @@ class Connection final : public PBackgroundSDBConnectionParent { Maybe MaybeDirectoryLockRef() const { AssertIsOnBackgroundThread(); - return ToMaybeRef(mDirectoryLock.get()); + return ToMaybeRef(mDirectoryLockHandle.get()); } nsIFileRandomAccessStream* GetFileRandomAccessStream() const { @@ -175,7 +174,7 @@ class Connection final : public PBackgroundSDBConnectionParent { void OnOpen( const nsACString& aOrigin, const nsAString& aName, - already_AddRefed aDirectoryLock, + ClientDirectoryLockHandle aDirectoryLockHandle, already_AddRefed aFileRandomAccessStream); void OnClose(); @@ -336,7 +335,7 @@ class OpenOp final : public ConnectionOperationBase { }; const SDBRequestOpenParams mParams; - RefPtr mDirectoryLock; + ClientDirectoryLockHandle mDirectoryLockHandle; nsCOMPtr mFileRandomAccessStream; // XXX Consider changing this to ClientMetadata. quota::OriginMetadata mOriginMetadata; @@ -374,7 +373,7 @@ class OpenOp final : public ConnectionOperationBase { NS_IMETHOD Run() override; - void DirectoryLockAcquired(ClientDirectoryLock* aLock); + void DirectoryLockAcquired(ClientDirectoryLockHandle aLockHandle); void DirectoryLockFailed(); }; @@ -689,20 +688,20 @@ void Connection::OnRequestFinished() { void Connection::OnOpen( const nsACString& aOrigin, const nsAString& aName, - already_AddRefed aDirectoryLock, + ClientDirectoryLockHandle aDirectoryLockHandle, already_AddRefed aFileRandomAccessStream) { AssertIsOnBackgroundThread(); MOZ_ASSERT(!aOrigin.IsEmpty()); MOZ_ASSERT(!aName.IsEmpty()); MOZ_ASSERT(mOrigin.IsEmpty()); MOZ_ASSERT(mName.IsEmpty()); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); MOZ_ASSERT(!mFileRandomAccessStream); MOZ_ASSERT(!mOpen); mOrigin = aOrigin; mName = aName; - mDirectoryLock = aDirectoryLock; + mDirectoryLockHandle = std::move(aDirectoryLockHandle); mFileRandomAccessStream = aFileRandomAccessStream; mOpen = true; @@ -712,7 +711,7 @@ void Connection::OnOpen( gOpenConnections->AppendElement(WrapNotNullUnchecked(this)); - if (mDirectoryLock->Invalidated()) { + if (mDirectoryLockHandle->Invalidated()) { AllowToClose(); } } @@ -720,14 +719,16 @@ void Connection::OnOpen( void Connection::OnClose() { AssertIsOnBackgroundThread(); MOZ_ASSERT(!mOrigin.IsEmpty()); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(mFileRandomAccessStream); MOZ_ASSERT(mOpen); mOrigin.Truncate(); mName.Truncate(); - DropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } mFileRandomAccessStream = nullptr; mOpen = false; @@ -1052,7 +1053,7 @@ OpenOp::OpenOp(Connection* aConnection, const SDBRequestParams& aParams) } OpenOp::~OpenOp() { - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle.IsInert()); MOZ_ASSERT(!mFileRandomAccessStream); MOZ_ASSERT(!mFileRandomAccessStreamOpen); MOZ_ASSERT_IF(OperationMayProceed(), @@ -1087,7 +1088,7 @@ nsresult OpenOp::Open() { nsresult OpenOp::FinishOpen() { AssertIsOnOwningThread(); MOZ_ASSERT(mOriginMetadata.mOrigin.IsEmpty()); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); MOZ_ASSERT(mState == State::FinishOpen); if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || @@ -1131,10 +1132,10 @@ nsresult OpenOp::FinishOpen() { ->OpenClientDirectory({mOriginMetadata, mozilla::dom::quota::Client::SDB}) ->Then( GetCurrentSerialEventTarget(), __func__, - [self = RefPtr(this)]( - const ClientDirectoryLockPromise::ResolveOrRejectValue& aValue) { + [self = RefPtr(this)](QuotaManager::ClientDirectoryLockHandlePromise:: + ResolveOrRejectValue&& aValue) { if (aValue.IsResolve()) { - self->DirectoryLockAcquired(aValue.ResolveValue()); + self->DirectoryLockAcquired(std::move(aValue.ResolveValue())); } else { self->DirectoryLockFailed(); } @@ -1268,11 +1269,13 @@ nsresult OpenOp::DatabaseWork() { void OpenOp::StreamClosedCallback() { AssertIsOnOwningThread(); MOZ_ASSERT(NS_FAILED(ResultCode())); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(mFileRandomAccessStream); MOZ_ASSERT(mFileRandomAccessStreamOpen); - DropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } mFileRandomAccessStream = nullptr; mFileRandomAccessStreamOpen = false; @@ -1298,19 +1301,19 @@ void OpenOp::OnSuccess() { AssertIsOnOwningThread(); MOZ_ASSERT(NS_SUCCEEDED(ResultCode())); MOZ_ASSERT(!mOriginMetadata.mOrigin.IsEmpty()); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); MOZ_ASSERT(mFileRandomAccessStream); MOZ_ASSERT(mFileRandomAccessStreamOpen); - RefPtr directoryLock; + ClientDirectoryLockHandle directoryLockHandle; nsCOMPtr fileRandomAccessStream; - mDirectoryLock.swap(directoryLock); + directoryLockHandle = std::move(mDirectoryLockHandle); mFileRandomAccessStream.swap(fileRandomAccessStream); mFileRandomAccessStreamOpen = false; GetConnection()->OnOpen(mOriginMetadata.mOrigin, mParams.name(), - directoryLock.forget(), + std::move(directoryLockHandle), fileRandomAccessStream.forget()); } @@ -1322,7 +1325,7 @@ void OpenOp::Cleanup() { // If we have an initialized file stream then the operation must have failed // and there must be a directory lock too. MOZ_ASSERT(NS_FAILED(ResultCode())); - MOZ_ASSERT(mDirectoryLock); + MOZ_ASSERT(mDirectoryLockHandle); // We must close the stream on the I/O thread before releasing it on this // thread. The directory lock can't be released either. @@ -1334,7 +1337,9 @@ void OpenOp::Cleanup() { new StreamHelper(mFileRandomAccessStream, callback); helper->AsyncClose(); } else { - SafeDropDirectoryLock(mDirectoryLock); + { + auto destroyingDirectoryLockHandle = std::move(mDirectoryLockHandle); + } mFileRandomAccessStream = nullptr; MOZ_ASSERT(!mFileRandomAccessStreamOpen); @@ -1386,12 +1391,12 @@ OpenOp::Run() { return NS_OK; } -void OpenOp::DirectoryLockAcquired(ClientDirectoryLock* aLock) { +void OpenOp::DirectoryLockAcquired(ClientDirectoryLockHandle aLockHandle) { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::DirectoryOpenPending); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); - mDirectoryLock = aLock; + mDirectoryLockHandle = std::move(aLockHandle); auto cleanupAndReturn = [self = RefPtr(this)](const nsresult rv) { self->MaybeSetFailureCode(rv); @@ -1403,7 +1408,7 @@ void OpenOp::DirectoryLockAcquired(ClientDirectoryLock* aLock) { MOZ_ALWAYS_SUCCEEDS(self->Run()); }; - if (mDirectoryLock->Invalidated()) { + if (mDirectoryLockHandle->Invalidated()) { return cleanupAndReturn(NS_ERROR_ABORT); } @@ -1413,7 +1418,7 @@ void OpenOp::DirectoryLockAcquired(ClientDirectoryLock* aLock) { void OpenOp::DirectoryLockFailed() { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::DirectoryOpenPending); - MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(!mDirectoryLockHandle); MaybeSetFailureCode(NS_ERROR_FAILURE);