diff --git a/dom/cache/Action.h b/dom/cache/Action.h index 721d89a3ba1d..a9d861c3ed1d 100644 --- a/dom/cache/Action.h +++ b/dom/cache/Action.h @@ -56,7 +56,7 @@ class Action : public SafeRefCounted { // Note: The "target" thread is determined when the Action is scheduled on // Context. The Action should not assume any particular thread is used. virtual void RunOnTarget(SafeRefPtr aResolver, - const ClientMetadata& aClientMetadata, + const Maybe& aClientMetadata, Data* aOptionalData) = 0; // Called on initiating thread when the Action is canceled. The Action is diff --git a/dom/cache/Context.cpp b/dom/cache/Context.cpp index 6568dc09c99f..67d7d33dbee0 100644 --- a/dom/cache/Context.cpp +++ b/dom/cache/Context.cpp @@ -32,7 +32,8 @@ class NullAction final : public Action { NullAction() = default; virtual void RunOnTarget(mozilla::SafeRefPtr aResolver, - const ClientMetadata&, Data*) override { + const mozilla::Maybe&, + Data*) override { // Resolve success immediately. This Action does no actual work. MOZ_DIAGNOSTIC_ASSERT(aResolver); aResolver->Resolve(NS_OK); @@ -215,7 +216,7 @@ class Context::QuotaInitRunnable final : public nsIRunnable, SafeRefPtr mInitAction; nsCOMPtr mInitiatingEventTarget; nsresult mResult; - ClientMetadata mClientMetadata; + Maybe mClientMetadata; RefPtr mDirectoryLock; State mState; Atomic mCanceled; @@ -233,7 +234,7 @@ void Context::QuotaInitRunnable::OpenDirectory() { RefPtr directoryLock = QuotaManager::Get()->CreateDirectoryLock( - PERSISTENCE_TYPE_DEFAULT, mClientMetadata, quota::Client::DOMCACHE, + PERSISTENCE_TYPE_DEFAULT, *mClientMetadata, quota::Client::DOMCACHE, /* aExclusive */ false); // DirectoryLock::Acquire() will hold a reference to us as a listener. We will @@ -252,7 +253,7 @@ void Context::QuotaInitRunnable::DirectoryLockAcquired(DirectoryLock* aLock) { mDirectoryLock = aLock; MOZ_DIAGNOSTIC_ASSERT(mDirectoryLock->Id() >= 0); - mClientMetadata.mDirectoryLockId = mDirectoryLock->Id(); + mClientMetadata->mDirectoryLockId = mDirectoryLock->Id(); if (mCanceled) { Complete(NS_ERROR_ABORT); @@ -352,8 +353,7 @@ Context::QuotaInitRunnable::Run() { QM_TRY_UNWRAP(auto principalMetadata, QuotaManager::GetInfoFromPrincipal(principal)); - static_cast(mClientMetadata) = { - std::move(principalMetadata), PERSISTENCE_TYPE_DEFAULT}; + mClientMetadata.emplace(std::move(principalMetadata)); mState = STATE_CREATE_QUOTA_MANAGER; @@ -416,10 +416,10 @@ Context::QuotaInitRunnable::Run() { QM_TRY( MOZ_TO_RESULT(quotaManager->EnsureTemporaryStorageIsInitialized())); - QM_TRY_UNWRAP(mClientMetadata.mDir, + QM_TRY_UNWRAP(mClientMetadata->mDir, quotaManager ->EnsureTemporaryOriginIsInitialized( - PERSISTENCE_TYPE_DEFAULT, mClientMetadata) + PERSISTENCE_TYPE_DEFAULT, *mClientMetadata) .map([](const auto& res) { return res.first; })); mState = STATE_RUN_ON_TARGET; @@ -453,7 +453,7 @@ Context::QuotaInitRunnable::Run() { // the marker file. If it wasn't opened successfully, then no need to // create a marker file anyway. if (NS_SUCCEEDED(resolver->Result())) { - MOZ_ALWAYS_SUCCEEDS(CreateMarkerFile(mClientMetadata)); + MOZ_ALWAYS_SUCCEEDS(CreateMarkerFile(*mClientMetadata)); } break; @@ -493,7 +493,7 @@ class Context::ActionRunnable final : public nsIRunnable, public: ActionRunnable(SafeRefPtr aContext, Data* aData, nsISerialEventTarget* aTarget, SafeRefPtr aAction, - const ClientMetadata& aClientMetadata) + const Maybe& aClientMetadata) : mContext(std::move(aContext)), mData(aData), mTarget(aTarget), @@ -587,7 +587,7 @@ class Context::ActionRunnable final : public nsIRunnable, RefPtr mData; nsCOMPtr mTarget; SafeRefPtr mAction; - const ClientMetadata mClientMetadata; + const Maybe mClientMetadata; nsCOMPtr mInitiatingThread; State mState; nsresult mResult; @@ -921,8 +921,8 @@ Context::~Context() { // Note, this may set the mOrphanedData flag. mManager->RemoveContext(*this); - if (mClientMetadata.mDir && !mOrphanedData) { - MOZ_ALWAYS_SUCCEEDS(DeleteMarkerFile(mClientMetadata)); + if (mClientMetadata && mClientMetadata->mDir && !mOrphanedData) { + MOZ_ALWAYS_SUCCEEDS(DeleteMarkerFile(*mClientMetadata)); } if (mNextContext) { @@ -994,14 +994,17 @@ void Context::DispatchAction(SafeRefPtr aAction, bool aDoomData) { AddActivity(*runnable); } -void Context::OnQuotaInit(nsresult aRv, const ClientMetadata& aClientMetadata, +void Context::OnQuotaInit(nsresult aRv, + const Maybe& aClientMetadata, already_AddRefed aDirectoryLock) { NS_ASSERT_OWNINGTHREAD(Context); MOZ_DIAGNOSTIC_ASSERT(mInitRunnable); mInitRunnable = nullptr; - mClientMetadata = aClientMetadata; + if (aClientMetadata) { + mClientMetadata.emplace(*aClientMetadata); + } // Always save the directory lock to ensure QuotaManager does not shutdown // before the Context has gone away. diff --git a/dom/cache/Context.h b/dom/cache/Context.h index 89c9a326f306..075908622131 100644 --- a/dom/cache/Context.h +++ b/dom/cache/Context.h @@ -152,8 +152,6 @@ class Context final : public SafeRefCounted { void AddActivity(Activity& aActivity); void RemoveActivity(Activity& aActivity); - const ClientMetadata& GetClientMetadata() const { return mClientMetadata; } - // Tell the Context that some state information has been orphaned in the // data store and won't be cleaned up. The Context will leave the marker // in place to trigger cleanup the next times its opened. @@ -179,7 +177,7 @@ class Context final : public SafeRefCounted { void Init(Maybe aOldContext); void Start(); void DispatchAction(SafeRefPtr aAction, bool aDoomData = false); - void OnQuotaInit(nsresult aRv, const ClientMetadata& aClientMetadata, + void OnQuotaInit(nsresult aRv, const Maybe& aClientMetadata, already_AddRefed aDirectoryLock); SafeRefPtr CreateThreadsafeHandle(); @@ -193,7 +191,7 @@ class Context final : public SafeRefCounted { RefPtr mData; State mState; bool mOrphanedData; - ClientMetadata mClientMetadata; + Maybe mClientMetadata; RefPtr mInitRunnable; SafeRefPtr mInitAction; nsTArray mPendingActions; diff --git a/dom/cache/DBAction.cpp b/dom/cache/DBAction.cpp index 07ac9cf48714..002facb27b29 100644 --- a/dom/cache/DBAction.cpp +++ b/dom/cache/DBAction.cpp @@ -56,11 +56,12 @@ DBAction::DBAction(Mode aMode) : mMode(aMode) {} DBAction::~DBAction() = default; void DBAction::RunOnTarget(SafeRefPtr aResolver, - const ClientMetadata& aClientMetadata, + const Maybe& aClientMetadata, Data* aOptionalData) { MOZ_ASSERT(!NS_IsMainThread()); MOZ_DIAGNOSTIC_ASSERT(aResolver); - MOZ_DIAGNOSTIC_ASSERT(aClientMetadata.mDir); + MOZ_DIAGNOSTIC_ASSERT(aClientMetadata); + MOZ_DIAGNOSTIC_ASSERT(aClientMetadata->mDir); if (IsCanceled()) { aResolver->Resolve(NS_ERROR_ABORT); @@ -72,7 +73,7 @@ void DBAction::RunOnTarget(SafeRefPtr aResolver, }; QM_TRY_INSPECT(const auto& dbDir, - CloneFileAndAppend(*aClientMetadata.mDir, u"cache"_ns), + CloneFileAndAppend(*(aClientMetadata->mDir), u"cache"_ns), QM_VOID, resolveErr); nsCOMPtr conn; @@ -84,7 +85,7 @@ void DBAction::RunOnTarget(SafeRefPtr aResolver, // If there is no previous Action, then we must open one. if (!conn) { - QM_TRY_UNWRAP(conn, OpenConnection(aClientMetadata, *dbDir), QM_VOID, + QM_TRY_UNWRAP(conn, OpenConnection(*aClientMetadata, *dbDir), QM_VOID, resolveErr); MOZ_DIAGNOSTIC_ASSERT(conn); @@ -100,7 +101,7 @@ void DBAction::RunOnTarget(SafeRefPtr aResolver, } } - RunWithDBOnTarget(std::move(aResolver), aClientMetadata, dbDir, conn); + RunWithDBOnTarget(std::move(aResolver), *aClientMetadata, dbDir, conn); } Result, nsresult> DBAction::OpenConnection( diff --git a/dom/cache/DBAction.h b/dom/cache/DBAction.h index e5c6886f0e79..3700512b24bd 100644 --- a/dom/cache/DBAction.h +++ b/dom/cache/DBAction.h @@ -42,7 +42,7 @@ class DBAction : public Action { private: void RunOnTarget(SafeRefPtr aResolver, - const ClientMetadata& aClientMetadata, + const Maybe& aClientMetadata, Data* aOptionalData) override; Result, nsresult> OpenConnection( diff --git a/dom/cache/FileUtils.cpp b/dom/cache/FileUtils.cpp index 3948f8341cb7..6965fccc4677 100644 --- a/dom/cache/FileUtils.cpp +++ b/dom/cache/FileUtils.cpp @@ -496,8 +496,12 @@ bool MarkerFileExists(const ClientMetadata& aClientMetadata) { QM_TRY_RETURN(MOZ_TO_RESULT_INVOKE(marker, Exists), false); } -nsresult RemoveNsIFileRecursively(const ClientMetadata& aClientMetadata, +nsresult RemoveNsIFileRecursively(const Maybe& aClientMetadata, nsIFile& aFile, const bool aTrackQuota) { + // XXX This assertion proves that we can remove aTrackQuota and just check + // aClientMetadata + MOZ_DIAGNOSTIC_ASSERT_IF(aTrackQuota, aClientMetadata); + QM_TRY_INSPECT(const auto& dirEntryKind, GetDirEntryKind(aFile)); switch (dirEntryKind) { @@ -531,8 +535,12 @@ nsresult RemoveNsIFileRecursively(const ClientMetadata& aClientMetadata, return NS_OK; } -nsresult RemoveNsIFile(const ClientMetadata& aClientMetadata, nsIFile& aFile, - const bool aTrackQuota) { +nsresult RemoveNsIFile(const Maybe& aClientMetadata, + nsIFile& aFile, const bool aTrackQuota) { + // XXX This assertion proves that we can remove aTrackQuota and just check + // aClientMetadata + MOZ_DIAGNOSTIC_ASSERT_IF(aTrackQuota, aClientMetadata); + int64_t fileSize = 0; if (aTrackQuota) { QM_TRY_INSPECT( @@ -562,7 +570,7 @@ nsresult RemoveNsIFile(const ClientMetadata& aClientMetadata, nsIFile& aFile, if (fileSize > 0) { MOZ_ASSERT(aTrackQuota); - DecreaseUsageForClientMetadata(aClientMetadata, fileSize); + DecreaseUsageForClientMetadata(*aClientMetadata, fileSize); } return NS_OK; diff --git a/dom/cache/FileUtils.h b/dom/cache/FileUtils.h index 37274d207cc9..017aaa1783fa 100644 --- a/dom/cache/FileUtils.h +++ b/dom/cache/FileUtils.h @@ -65,25 +65,50 @@ nsresult BodyDeleteOrphanedFiles(const ClientMetadata& aClientMetadata, // created by other threads. Note that if the files are not expected, we should // be safe to remove them in any case. template -nsresult BodyTraverseFiles(const ClientMetadata& aClientMetadata, +nsresult BodyTraverseFiles(const Maybe& aClientMetadata, nsIFile& aBodyDir, const Func& aHandleFileFunc, bool aCanRemoveFiles, bool aTrackQuota = true); +// XXX Remove this method when all callers properly wrap aClientMetadata with +// Some/Nothing +template +nsresult BodyTraverseFiles(const ClientMetadata& aClientMetadata, + nsIFile& aBodyDir, const Func& aHandleFileFunc, + bool aCanRemoveFiles, bool aTrackQuota = true) { + return BodyTraverseFiles(Some(aClientMetadata), aBodyDir, aHandleFileFunc, + aCanRemoveFiles, aTrackQuota); +} + nsresult CreateMarkerFile(const ClientMetadata& aClientMetadata); nsresult DeleteMarkerFile(const ClientMetadata& aClientMetadata); bool MarkerFileExists(const ClientMetadata& aClientMetadata); -nsresult RemoveNsIFileRecursively(const ClientMetadata& aClientMetadata, +nsresult RemoveNsIFileRecursively(const Maybe& aClientMetadata, nsIFile& aFile, bool aTrackQuota = true); +// XXX Remove this method when all callers properly wrap aClientMetadata with +// Some/Nothing +inline nsresult RemoveNsIFileRecursively(const ClientMetadata& aClientMetadata, + nsIFile& aFile, + bool aTrackQuota = true) { + return RemoveNsIFileRecursively(Some(aClientMetadata), aFile, aTrackQuota); +} + // Delete a file that you think exists. If the file doesn't exist, an error // will not be returned, but warning telemetry will be generated! So only call // this on files that you know exist (idempotent usage, but it's not // recommended). -nsresult RemoveNsIFile(const ClientMetadata& aClientMetadata, nsIFile& aFile, - bool aTrackQuota = true); +nsresult RemoveNsIFile(const Maybe& aClientMetadata, + nsIFile& aFile, bool aTrackQuota = true); + +// XXX Remove this method when all callers properly wrap aClientMetadata with +// Some/Nothing +inline nsresult RemoveNsIFile(const ClientMetadata& aClientMetadata, + nsIFile& aFile, bool aTrackQuota = true) { + return RemoveNsIFile(Some(aClientMetadata), aFile, aTrackQuota); +} void DecreaseUsageForClientMetadata(const ClientMetadata& aClientMetadata, int64_t aUpdatingSize); diff --git a/dom/cache/FileUtilsImpl.h b/dom/cache/FileUtilsImpl.h index 16b8295947bd..e67f0b136e09 100644 --- a/dom/cache/FileUtilsImpl.h +++ b/dom/cache/FileUtilsImpl.h @@ -15,9 +15,13 @@ namespace dom { namespace cache { template -nsresult BodyTraverseFiles(const ClientMetadata& aClientMetadata, +nsresult BodyTraverseFiles(const Maybe& aClientMetadata, nsIFile& aBodyDir, const Func& aHandleFileFunc, const bool aCanRemoveFiles, const bool aTrackQuota) { + // XXX This assertion proves that we can remove aTrackQuota and just check + // aClientMetadata.isSome() + MOZ_DIAGNOSTIC_ASSERT_IF(aTrackQuota, aClientMetadata); + #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED { nsCOMPtr parentFile; diff --git a/dom/cache/Manager.cpp b/dom/cache/Manager.cpp index 5f17a050e1e4..efcdba7840ae 100644 --- a/dom/cache/Manager.cpp +++ b/dom/cache/Manager.cpp @@ -172,9 +172,11 @@ class DeleteOrphanedBodyAction final : public Action { : mDeletedBodyIdList{aBodyId} {} void RunOnTarget(SafeRefPtr aResolver, - const ClientMetadata& aClientMetadata, Data*) override { + const Maybe& aClientMetadata, + Data*) override { MOZ_DIAGNOSTIC_ASSERT(aResolver); - MOZ_DIAGNOSTIC_ASSERT(aClientMetadata.mDir); + MOZ_DIAGNOSTIC_ASSERT(aClientMetadata); + MOZ_DIAGNOSTIC_ASSERT(aClientMetadata->mDir); // Note that since DeleteOrphanedBodyAction isn't used while the context is // being initialized, we don't need to check for cancellation here. @@ -184,11 +186,11 @@ class DeleteOrphanedBodyAction final : public Action { }; QM_TRY_INSPECT(const auto& dbDir, - CloneFileAndAppend(*aClientMetadata.mDir, u"cache"_ns), + CloneFileAndAppend(*aClientMetadata->mDir, u"cache"_ns), QM_VOID, resolve); QM_TRY(MOZ_TO_RESULT( - BodyDeleteFiles(aClientMetadata, *dbDir, mDeletedBodyIdList)), + BodyDeleteFiles(*aClientMetadata, *dbDir, mDeletedBodyIdList)), QM_VOID, resolve); aResolver->Resolve(NS_OK); @@ -554,7 +556,7 @@ class Manager::DeleteOrphanedCacheAction final : public SyncDBAction { mManager->NoteOrphanedBodyIdList(mDeletionInfo.mDeletedBodyIdList); if (mDeletionInfo.mDeletedPaddingSize > 0) { - DecreaseUsageForClientMetadata(mClientMetadata.ref(), + DecreaseUsageForClientMetadata(*mClientMetadata, mDeletionInfo.mDeletedPaddingSize); } @@ -856,7 +858,7 @@ class Manager::CachePutAllAction final : public DBAction { if (e.mResponse.type() == ResponseType::Opaque) { // It'll generate padding if we've not set it yet. QM_TRY(MOZ_TO_RESULT(BodyMaybeUpdatePaddingSize( - mClientMetadata.ref(), *mDBDir, e.mResponseBodyId, + *mClientMetadata, *mDBDir, e.mResponseBodyId, e.mResponse.paddingInfo(), &e.mResponse.paddingSize()))); MOZ_DIAGNOSTIC_ASSERT(INT64_MAX - e.mResponse.paddingSize() >= @@ -913,8 +915,7 @@ class Manager::CachePutAllAction final : public DBAction { mManager->NoteOrphanedBodyIdList(mDeletedBodyIdList); if (mDeletedPaddingSize > 0) { - DecreaseUsageForClientMetadata(mClientMetadata.ref(), - mDeletedPaddingSize); + DecreaseUsageForClientMetadata(*mClientMetadata, mDeletedPaddingSize); } Listener* listener = mManager->GetListener(mListenerId); @@ -1033,10 +1034,9 @@ class Manager::CachePutAllAction final : public DBAction { // Clean up any files we might have written before hitting the error. if (NS_FAILED(aRv)) { - BodyDeleteFiles(mClientMetadata.ref(), *mDBDir, mBodyIdWrittenList); + BodyDeleteFiles(*mClientMetadata, *mDBDir, mBodyIdWrittenList); if (mUpdatedPaddingSize > 0) { - DecreaseUsageForClientMetadata(mClientMetadata.ref(), - mUpdatedPaddingSize); + DecreaseUsageForClientMetadata(*mClientMetadata, mUpdatedPaddingSize); } } @@ -1137,7 +1137,7 @@ class Manager::CacheDeleteAction final : public Manager::BaseAction { mManager->NoteOrphanedBodyIdList(mDeletionInfo.mDeletedBodyIdList); if (mDeletionInfo.mDeletedPaddingSize > 0) { - DecreaseUsageForClientMetadata(mClientMetadata.ref(), + DecreaseUsageForClientMetadata(*mClientMetadata, mDeletionInfo.mDeletedPaddingSize); } diff --git a/dom/cache/QuotaClient.cpp b/dom/cache/QuotaClient.cpp index 830153764df2..67da7a03bc39 100644 --- a/dom/cache/QuotaClient.cpp +++ b/dom/cache/QuotaClient.cpp @@ -64,8 +64,8 @@ Result GetBodyUsage(nsIFile& aMorgueDir, if (dirEntryKind != nsIFileKind::ExistsAsDirectory) { if (dirEntryKind == nsIFileKind::ExistsAsFile) { - const DebugOnly result = RemoveNsIFile( - ClientMetadata{}, *bodyDir, /* aTrackQuota */ false); + const DebugOnly result = + RemoveNsIFile(Nothing(), *bodyDir, /* aTrackQuota */ false); // Try to remove the unexpected files, and keep moving on even if it // fails because it might be created by virus or the operation // system @@ -108,8 +108,7 @@ Result GetBodyUsage(nsIFile& aMorgueDir, // warning in the reports is not desired). QM_TRY(QM_OR_ELSE_LOG_VERBOSE_IF( // Expression. - MOZ_TO_RESULT(BodyTraverseFiles(ClientMetadata{}, *bodyDir, - getUsage, + MOZ_TO_RESULT(BodyTraverseFiles(Nothing(), *bodyDir, getUsage, /* aCanRemoveFiles */ true, /* aTrackQuota */ false)), // Predicate. @@ -123,8 +122,7 @@ Result GetBodyUsage(nsIFile& aMorgueDir, Result GetPaddingSizeFromDB( nsIFile& aDir, nsIFile& aDBFile, const OriginMetadata& aOriginMetadata) { - ClientMetadata clientMetadata; - static_cast(clientMetadata) = aOriginMetadata; + ClientMetadata clientMetadata(aOriginMetadata); // clientMetadata.mDirectoryLockId must be -1 (which is default for new // ClientMetadata) because this method should only be called from // QuotaClient::InitOrigin when the temporary storage hasn't been initialized @@ -217,9 +215,8 @@ Result CacheQuotaClient::InitOrigin( QM_TRY_INSPECT(const auto& morgueDir, CloneFileAndAppend(*dir, kMorgueDirectoryFilename)); - ClientMetadata dummy; QM_TRY(MOZ_TO_RESULT(mozilla::dom::cache::RemoveNsIFileRecursively( - dummy, *morgueDir, + Nothing(), *morgueDir, /* aTrackQuota */ false))); return nsCOMPtr{nullptr}; diff --git a/dom/cache/Types.h b/dom/cache/Types.h index 2ce77ddb8417..7696ae7669d7 100644 --- a/dom/cache/Types.h +++ b/dom/cache/Types.h @@ -29,10 +29,22 @@ static const Namespace INVALID_NAMESPACE = NUMBER_OF_NAMESPACES; using CacheId = int64_t; static const CacheId INVALID_CACHE_ID = -1; -// XXX Consider inheritance from ClientMetadata. -struct ClientMetadata : quota::OriginMetadata { +struct ClientMetadata : quota::ClientMetadata { nsCOMPtr mDir; int64_t mDirectoryLockId = -1; + + explicit ClientMetadata(quota::PrincipalMetadata aPrincipalMetadata) + : quota::ClientMetadata( + quota::OriginMetadata{std::move(aPrincipalMetadata), + quota::PERSISTENCE_TYPE_DEFAULT}, + quota::Client::Type::DOMCACHE) {} + + explicit ClientMetadata(quota::OriginMetadata aOriginMetadata) + : quota::ClientMetadata(std::move(aOriginMetadata), + quota::Client::Type::DOMCACHE) { + MOZ_DIAGNOSTIC_ASSERT(aOriginMetadata.mPersistenceType == + quota::PERSISTENCE_TYPE_DEFAULT); + } }; struct DeletionInfo {