Bug 1913561 - Add support for initializing temporary storage to QuotaManager::OpenStorageDirectory; r=dom-storage-reviewers,jari

QuotaManager::OpenStorageDirectory can now detect the requested persistence
scope and initialize temporary storage if it's needed.

Differential Revision: https://phabricator.services.mozilla.com/D195393
This commit is contained in:
Jan Varga 2024-10-06 22:04:46 +00:00
parent ab40ae49e7
commit 9fc642a657
7 changed files with 83 additions and 9 deletions

View File

@ -13044,7 +13044,8 @@ nsresult Maintenance::OpenDirectory() {
->OpenStorageDirectory(
PersistenceScope::CreateFromNull(), OriginScope::FromNull(),
Nullable<Client::Type>(Client::IDB), /* aExclusive */ false,
DirectoryLockCategory::None, SomeRef(mPendingDirectoryLock))
/* aInitializeOrigins */ false, DirectoryLockCategory::None,
SomeRef(mPendingDirectoryLock))
->Then(GetCurrentSerialEventTarget(), __func__,
[self = RefPtr(this)](
const UniversalDirectoryLockPromise::ResolveOrRejectValue&

View File

@ -5115,24 +5115,42 @@ RefPtr<BoolPromise> QuotaManager::TemporaryStorageInitialized() {
RefPtr<UniversalDirectoryLockPromise> QuotaManager::OpenStorageDirectory(
const PersistenceScope& aPersistenceScope, const OriginScope& aOriginScope,
const Nullable<Client::Type>& aClientType, bool aExclusive,
DirectoryLockCategory aCategory,
bool aInitializeOrigins, DirectoryLockCategory aCategory,
Maybe<RefPtr<UniversalDirectoryLock>&> aPendingDirectoryLockOut) {
AssertIsOnOwningThread();
nsTArray<RefPtr<BoolPromise>> promises;
RefPtr<UniversalDirectoryLock> storageDirectoryLock =
CreateDirectoryLockInternal(PersistenceScope::CreateFromNull(),
OriginScope::FromNull(),
Nullable<Client::Type>(),
/* aExclusive */ false);
RefPtr<BoolPromise> storageDirectoryLockPromise;
if (mStorageInitialized &&
!IsDirectoryLockBlockedByUninitStorageOperation(storageDirectoryLock)) {
storageDirectoryLock = nullptr;
storageDirectoryLockPromise = BoolPromise::CreateAndResolve(true, __func__);
} else {
storageDirectoryLockPromise = storageDirectoryLock->Acquire();
promises.AppendElement(storageDirectoryLock->Acquire());
}
RefPtr<UniversalDirectoryLock> temporaryStorageDirectoryLock;
if (aInitializeOrigins &&
MatchesBestEffortPersistenceScope(aPersistenceScope)) {
temporaryStorageDirectoryLock = CreateDirectoryLockInternal(
PersistenceScope::CreateFromSet(PERSISTENCE_TYPE_TEMPORARY,
PERSISTENCE_TYPE_DEFAULT),
OriginScope::FromNull(), Nullable<Client::Type>(),
/* aExclusive */ false);
if (mTemporaryStorageInitialized &&
!IsDirectoryLockBlockedByUninitStorageOperation(
temporaryStorageDirectoryLock)) {
temporaryStorageDirectoryLock = nullptr;
} else {
promises.AppendElement(temporaryStorageDirectoryLock->Acquire());
}
}
RefPtr<UniversalDirectoryLock> universalDirectoryLock =
@ -5146,7 +5164,15 @@ RefPtr<UniversalDirectoryLockPromise> QuotaManager::OpenStorageDirectory(
aPendingDirectoryLockOut.ref() = universalDirectoryLock;
}
return storageDirectoryLockPromise
return BoolPromise::All(GetCurrentSerialEventTarget(), promises)
->Then(
GetCurrentSerialEventTarget(), __func__,
[](const CopyableTArray<bool>& aResolveValues) {
return BoolPromise::CreateAndResolve(true, __func__);
},
[](nsresult aRejectValue) {
return BoolPromise::CreateAndReject(aRejectValue, __func__);
})
->Then(GetCurrentSerialEventTarget(), __func__,
[self = RefPtr(this),
storageDirectoryLock = std::move(storageDirectoryLock)](
@ -5164,6 +5190,26 @@ RefPtr<UniversalDirectoryLockPromise> QuotaManager::OpenStorageDirectory(
return self->InitializeStorage(std::move(storageDirectoryLock));
})
->Then(
GetCurrentSerialEventTarget(), __func__,
[self = RefPtr(this), temporaryStorageDirectoryLock =
std::move(temporaryStorageDirectoryLock)](
const BoolPromise::ResolveOrRejectValue& aValue) mutable {
if (aValue.IsReject()) {
SafeDropDirectoryLockIfNotDropped(temporaryStorageDirectoryLock);
return BoolPromise::CreateAndReject(aValue.RejectValue(),
__func__);
}
if (!temporaryStorageDirectoryLock) {
return BoolPromise::CreateAndResolve(true, __func__);
}
return self->InitializeTemporaryStorage(
std::move(temporaryStorageDirectoryLock));
})
->Then(GetCurrentSerialEventTarget(), __func__,
[universalDirectoryLockPromise =
std::move(universalDirectoryLockPromise)](

View File

@ -79,6 +79,7 @@ class OpenStorageDirectoryHelper : public Base {
const PersistenceScope& aPersistenceScope,
const OriginScope& aOriginScope,
const Nullable<Client::Type>& aClientType, bool aExclusive,
bool aInitializeOrigins = false,
DirectoryLockCategory aCategory = DirectoryLockCategory::None);
RefPtr<UniversalDirectoryLock> mDirectoryLock;
@ -954,10 +955,10 @@ template <class Base>
RefPtr<BoolPromise> OpenStorageDirectoryHelper<Base>::OpenStorageDirectory(
const PersistenceScope& aPersistenceScope, const OriginScope& aOriginScope,
const Nullable<Client::Type>& aClientType, bool aExclusive,
const DirectoryLockCategory aCategory) {
bool aInitializeOrigins, const DirectoryLockCategory aCategory) {
return Base::mQuotaManager
->OpenStorageDirectory(aPersistenceScope, aOriginScope, aClientType,
aExclusive, aCategory)
aExclusive, aInitializeOrigins, aCategory)
->Then(GetCurrentSerialEventTarget(), __func__,
[self = RefPtr(this)](
UniversalDirectoryLockPromise::ResolveOrRejectValue&& aValue) {
@ -2093,6 +2094,7 @@ RefPtr<BoolPromise> ClearStorageOp::OpenDirectory() {
return OpenStorageDirectory(PersistenceScope::CreateFromNull(),
OriginScope::FromNull(), Nullable<Client::Type>(),
/* aExclusive */ true,
/* aInitializeOrigins */ false,
DirectoryLockCategory::UninitStorage);
}

View File

@ -0,0 +1,20 @@
/* -*- 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/. */
#include "PersistenceScope.h"
namespace mozilla::dom::quota {
bool MatchesBestEffortPersistenceScope(
const PersistenceScope& aPersistenceScope) {
static PersistenceScope scope(PersistenceScope::CreateFromSet(
PERSISTENCE_TYPE_TEMPORARY, PERSISTENCE_TYPE_DEFAULT,
PERSISTENCE_TYPE_PRIVATE));
return aPersistenceScope.Matches(scope);
}
} // namespace mozilla::dom::quota

View File

@ -163,6 +163,9 @@ class PersistenceScope {
bool operator==(const PersistenceScope& aOther) = delete;
};
bool MatchesBestEffortPersistenceScope(
const PersistenceScope& aPersistenceScope);
} // namespace mozilla::dom::quota
#endif // DOM_QUOTA_PERSISTENCESCOPE_H_

View File

@ -277,6 +277,7 @@ class QuotaManager final : public BackgroundThreadObject {
const PersistenceScope& aPersistenceScope,
const OriginScope& aOriginScope,
const Nullable<Client::Type>& aClientType, bool aExclusive,
bool aInitializeOrigins = false,
DirectoryLockCategory aCategory = DirectoryLockCategory::None,
Maybe<RefPtr<UniversalDirectoryLock>&> aPendingDirectoryLockOut =
Nothing());

View File

@ -121,6 +121,7 @@ UNIFIED_SOURCES += [
"OriginOperationBase.cpp",
"OriginOperations.cpp",
"OriginParser.cpp",
"PersistenceScope.cpp",
"PersistenceType.cpp",
"PromiseUtils.cpp",
"QMResult.cpp",