Bug 1719281 - QM: Add a generic wrapper for running initializations; r=dom-storage-reviewers,asuth

Differential Revision: https://phabricator.services.mozilla.com/D119182
This commit is contained in:
Jan Varga 2021-07-31 12:37:36 +00:00
Родитель edbd3850d8
Коммит f269c78d92
8 изменённых файлов: 185 добавлений и 144 удалений

Просмотреть файл

@ -3096,6 +3096,22 @@ bool VerifyOriginKey(const nsACString& aOriginKey,
return true; return true;
} }
LSInitializationInfo& MutableInitializationInfoRef(const CreateIfNonExistent&) {
if (!gInitializationInfo) {
gInitializationInfo = new LSInitializationInfo();
}
return *gInitializationInfo;
}
nsresult ExecuteOriginInitialization(
const nsACString& aOrigin, const LSOriginInitialization aInitialization,
const nsresult aRv) {
return ExecuteInitialization(
MutableInitializationInfoRef(CreateIfNonExistent{})
.MutableOriginInitializationInfoRef(aOrigin, CreateIfNonExistent{}),
aInitialization, aRv);
}
} // namespace } // namespace
/******************************************************************************* /*******************************************************************************
@ -6781,24 +6797,16 @@ nsresult PrepareDatastoreOp::DatabaseWork() {
MOZ_ASSERT(mState == State::Nesting); MOZ_ASSERT(mState == State::Nesting);
MOZ_ASSERT(mNestedState == NestedState::DatabaseWorkOpen); MOZ_ASSERT(mNestedState == NestedState::DatabaseWorkOpen);
// XXX Maybe add GetOrCreateInitializationInfo for this. const auto innerFunc = [this]() -> nsresult {
if (!gInitializationInfo) {
gInitializationInfo = new LSInitializationInfo();
}
auto& originInitializationInfo =
gInitializationInfo->MutableOriginInitializationInfoRef(
mOriginMetadata.mOrigin);
const auto firstInitializationAttempt =
originInitializationInfo.FirstInitializationAttempt(
LSOriginInitialization::Datastore);
auto rv = [&firstInitializationAttempt, this]() -> nsresult {
// XXX This function is too long, refactor it into helper functions for // XXX This function is too long, refactor it into helper functions for
// readability. // readability.
const auto maybeExtraInfo = const auto maybeExtraInfo =
firstInitializationAttempt.Pending() MutableInitializationInfoRef(CreateIfNonExistent{})
.MutableOriginInitializationInfoRef(mOriginMetadata.mOrigin,
CreateIfNonExistent{})
.FirstInitializationAttemptPending(
LSOriginInitialization::Datastore)
? Some(ScopedLogExtraInfo{ ? Some(ScopedLogExtraInfo{
ScopedLogExtraInfo::kTagContext, ScopedLogExtraInfo::kTagContext,
"dom::localstorage::FirstOriginInitializationAttempt::Datastore"_ns}) "dom::localstorage::FirstOriginInitializationAttempt::Datastore"_ns})
@ -7052,11 +7060,10 @@ nsresult PrepareDatastoreOp::DatabaseWork() {
QM_TRY(OwningEventTarget()->Dispatch(this, NS_DISPATCH_NORMAL)); QM_TRY(OwningEventTarget()->Dispatch(this, NS_DISPATCH_NORMAL));
return NS_OK; return NS_OK;
}(); };
firstInitializationAttempt.MaybeRecord(rv); return ExecuteOriginInitialization(
mOriginMetadata.mOrigin, LSOriginInitialization::Datastore, innerFunc());
return rv;
} }
nsresult PrepareDatastoreOp::DatabaseNotAvailable() { nsresult PrepareDatastoreOp::DatabaseNotAvailable() {

Просмотреть файл

@ -11,6 +11,10 @@
#include <mozilla/dom/quota/FirstInitializationAttempts.h> #include <mozilla/dom/quota/FirstInitializationAttempts.h>
#include "nsTHashMap.h" #include "nsTHashMap.h"
namespace mozilla {
struct CreateIfNonExistent;
}
namespace mozilla::dom { namespace mozilla::dom {
enum class LSOriginInitialization { enum class LSOriginInitialization {
@ -29,7 +33,7 @@ class LSInitializationInfo final {
public: public:
LSOriginInitializationInfo& MutableOriginInitializationInfoRef( LSOriginInitializationInfo& MutableOriginInitializationInfoRef(
const nsACString& aOrigin) { const nsACString& aOrigin, const CreateIfNonExistent&) {
return mOriginInitializationInfos.LookupOrInsert(aOrigin); return mOriginInitializationInfos.LookupOrInsert(aOrigin);
} }
}; };

Просмотреть файл

@ -4238,13 +4238,15 @@ nsresult QuotaManager::LoadQuota() {
QM_TRY(([&]() -> Result<Ok, nsresult> { QM_TRY(([&]() -> Result<Ok, nsresult> {
QM_TRY(([this, type] { QM_TRY(([this, type] {
const nsresult rv = InitializeRepository(type); const auto innerFunc = [type, this]() -> nsresult {
mInitializationInfo.MaybeRecordFirstInitializationAttempt( return InitializeRepository(type);
};
return ExecuteInitialization(
type == PERSISTENCE_TYPE_DEFAULT type == PERSISTENCE_TYPE_DEFAULT
? Initialization::DefaultRepository ? Initialization::DefaultRepository
: Initialization::TemporaryRepository, : Initialization::TemporaryRepository,
rv); innerFunc());
return rv;
}()), }()),
OK_IN_NIGHTLY_PROPAGATE_IN_OTHERS, statusKeeperFunc); OK_IN_NIGHTLY_PROPAGATE_IN_OTHERS, statusKeeperFunc);
@ -5006,7 +5008,7 @@ QuotaManager::UpgradeFromIndexedDBDirectoryToPersistentStorageDirectory(
AssertIsOnIOThread(); AssertIsOnIOThread();
MOZ_ASSERT(aIndexedDBDir); MOZ_ASSERT(aIndexedDBDir);
auto rv = [this, &aIndexedDBDir]() -> nsresult { const auto innerFunc = [this, &aIndexedDBDir]() -> nsresult {
bool isDirectory; bool isDirectory;
QM_TRY(aIndexedDBDir->IsDirectory(&isDirectory)); QM_TRY(aIndexedDBDir->IsDirectory(&isDirectory));
@ -5049,12 +5051,10 @@ QuotaManager::UpgradeFromIndexedDBDirectoryToPersistentStorageDirectory(
nsLiteralString(PERSISTENT_DIRECTORY_NAME))); nsLiteralString(PERSISTENT_DIRECTORY_NAME)));
return NS_OK; return NS_OK;
}(); };
mInitializationInfo.MaybeRecordFirstInitializationAttempt( return ExecuteInitialization(Initialization::UpgradeFromIndexedDBDirectory,
Initialization::UpgradeFromIndexedDBDirectory, rv); innerFunc());
return rv;
} }
nsresult nsresult
@ -5063,7 +5063,7 @@ QuotaManager::UpgradeFromPersistentStorageDirectoryToDefaultStorageDirectory(
AssertIsOnIOThread(); AssertIsOnIOThread();
MOZ_ASSERT(aPersistentStorageDir); MOZ_ASSERT(aPersistentStorageDir);
auto rv = [this, &aPersistentStorageDir]() -> nsresult { const auto innerFunc = [this, &aPersistentStorageDir]() -> nsresult {
QM_TRY_INSPECT(const bool& isDirectory, QM_TRY_INSPECT(const bool& isDirectory,
MOZ_TO_RESULT_INVOKE(aPersistentStorageDir, IsDirectory)); MOZ_TO_RESULT_INVOKE(aPersistentStorageDir, IsDirectory));
@ -5128,12 +5128,9 @@ QuotaManager::UpgradeFromPersistentStorageDirectoryToDefaultStorageDirectory(
nullptr, nsLiteralString(DEFAULT_DIRECTORY_NAME))); nullptr, nsLiteralString(DEFAULT_DIRECTORY_NAME)));
return NS_OK; return NS_OK;
}(); };
return ExecuteInitialization(
mInitializationInfo.MaybeRecordFirstInitializationAttempt( Initialization::UpgradeFromPersistentStorageDirectory, innerFunc());
Initialization::UpgradeFromPersistentStorageDirectory, rv);
return rv;
} }
template <typename Helper> template <typename Helper>
@ -5181,17 +5178,15 @@ nsresult QuotaManager::UpgradeStorageFrom0_0To1_0(
AssertIsOnIOThread(); AssertIsOnIOThread();
MOZ_ASSERT(aConnection); MOZ_ASSERT(aConnection);
auto rv = [this, &aConnection]() -> nsresult { const auto innerFunc = [this, &aConnection]() -> nsresult {
QM_TRY(UpgradeStorage<UpgradeStorageFrom0_0To1_0Helper>( QM_TRY(UpgradeStorage<UpgradeStorageFrom0_0To1_0Helper>(
0, MakeStorageVersion(1, 0), aConnection)); 0, MakeStorageVersion(1, 0), aConnection));
return NS_OK; return NS_OK;
}(); };
mInitializationInfo.MaybeRecordFirstInitializationAttempt( return ExecuteInitialization(Initialization::UpgradeStorageFrom0_0To1_0,
Initialization::UpgradeStorageFrom0_0To1_0, rv); innerFunc());
return rv;
} }
nsresult QuotaManager::UpgradeStorageFrom1_0To2_0( nsresult QuotaManager::UpgradeStorageFrom1_0To2_0(
@ -5266,17 +5261,15 @@ nsresult QuotaManager::UpgradeStorageFrom1_0To2_0(
// manager directories without the ".files" suffix then prevent current // manager directories without the ".files" suffix then prevent current
// Firefox from initializing and using the storage. // Firefox from initializing and using the storage.
auto rv = [this, &aConnection]() -> nsresult { const auto innerFunc = [this, &aConnection]() -> nsresult {
QM_TRY(UpgradeStorage<UpgradeStorageFrom1_0To2_0Helper>( QM_TRY(UpgradeStorage<UpgradeStorageFrom1_0To2_0Helper>(
MakeStorageVersion(1, 0), MakeStorageVersion(2, 0), aConnection)); MakeStorageVersion(1, 0), MakeStorageVersion(2, 0), aConnection));
return NS_OK; return NS_OK;
}(); };
mInitializationInfo.MaybeRecordFirstInitializationAttempt( return ExecuteInitialization(Initialization::UpgradeStorageFrom1_0To2_0,
Initialization::UpgradeStorageFrom1_0To2_0, rv); innerFunc());
return rv;
} }
nsresult QuotaManager::UpgradeStorageFrom2_0To2_1( nsresult QuotaManager::UpgradeStorageFrom2_0To2_1(
@ -5287,17 +5280,15 @@ nsresult QuotaManager::UpgradeStorageFrom2_0To2_1(
// The upgrade is mainly to create a directory padding file in DOM Cache // The upgrade is mainly to create a directory padding file in DOM Cache
// directory to record the overall padding size of an origin. // directory to record the overall padding size of an origin.
auto rv = [this, &aConnection]() -> nsresult { const auto innerFunc = [this, &aConnection]() -> nsresult {
QM_TRY(UpgradeStorage<UpgradeStorageFrom2_0To2_1Helper>( QM_TRY(UpgradeStorage<UpgradeStorageFrom2_0To2_1Helper>(
MakeStorageVersion(2, 0), MakeStorageVersion(2, 1), aConnection)); MakeStorageVersion(2, 0), MakeStorageVersion(2, 1), aConnection));
return NS_OK; return NS_OK;
}(); };
mInitializationInfo.MaybeRecordFirstInitializationAttempt( return ExecuteInitialization(Initialization::UpgradeStorageFrom2_0To2_1,
Initialization::UpgradeStorageFrom2_0To2_1, rv); innerFunc());
return rv;
} }
nsresult QuotaManager::UpgradeStorageFrom2_1To2_2( nsresult QuotaManager::UpgradeStorageFrom2_1To2_2(
@ -5308,17 +5299,15 @@ nsresult QuotaManager::UpgradeStorageFrom2_1To2_2(
// The upgrade is mainly to clean obsolete origins in the repositoies, remove // The upgrade is mainly to clean obsolete origins in the repositoies, remove
// asmjs client, and ".tmp" file in the idb folers. // asmjs client, and ".tmp" file in the idb folers.
auto rv = [this, &aConnection]() -> nsresult { const auto innerFunc = [this, &aConnection]() -> nsresult {
QM_TRY(UpgradeStorage<UpgradeStorageFrom2_1To2_2Helper>( QM_TRY(UpgradeStorage<UpgradeStorageFrom2_1To2_2Helper>(
MakeStorageVersion(2, 1), MakeStorageVersion(2, 2), aConnection)); MakeStorageVersion(2, 1), MakeStorageVersion(2, 2), aConnection));
return NS_OK; return NS_OK;
}(); };
mInitializationInfo.MaybeRecordFirstInitializationAttempt( return ExecuteInitialization(Initialization::UpgradeStorageFrom2_1To2_2,
Initialization::UpgradeStorageFrom2_1To2_2, rv); innerFunc());
return rv;
} }
nsresult QuotaManager::UpgradeStorageFrom2_2To2_3( nsresult QuotaManager::UpgradeStorageFrom2_2To2_3(
@ -5326,7 +5315,7 @@ nsresult QuotaManager::UpgradeStorageFrom2_2To2_3(
AssertIsOnIOThread(); AssertIsOnIOThread();
MOZ_ASSERT(aConnection); MOZ_ASSERT(aConnection);
auto rv = [&aConnection]() -> nsresult { const auto innerFunc = [&aConnection]() -> nsresult {
// Table `database` // Table `database`
QM_TRY(aConnection->ExecuteSimpleSQL( QM_TRY(aConnection->ExecuteSimpleSQL(
nsLiteralCString("CREATE TABLE database" nsLiteralCString("CREATE TABLE database"
@ -5349,12 +5338,10 @@ nsresult QuotaManager::UpgradeStorageFrom2_2To2_3(
QM_TRY(aConnection->SetSchemaVersion(MakeStorageVersion(2, 3))); QM_TRY(aConnection->SetSchemaVersion(MakeStorageVersion(2, 3)));
return NS_OK; return NS_OK;
}(); };
mInitializationInfo.MaybeRecordFirstInitializationAttempt( return ExecuteInitialization(Initialization::UpgradeStorageFrom2_2To2_3,
Initialization::UpgradeStorageFrom2_2To2_3, rv); innerFunc());
return rv;
} }
nsresult QuotaManager::MaybeRemoveLocalStorageDataAndArchive( nsresult QuotaManager::MaybeRemoveLocalStorageDataAndArchive(
@ -5996,15 +5983,10 @@ Result<Ok, nsresult> QuotaManager::CreateEmptyLocalStorageArchive(
nsresult QuotaManager::EnsureStorageIsInitialized() { nsresult QuotaManager::EnsureStorageIsInitialized() {
DiagnosticAssertIsOnIOThread(); DiagnosticAssertIsOnIOThread();
const auto firstInitializationAttempt = const auto innerFunc = [this]() -> nsresult {
mInitializationInfo.FirstInitializationAttempt(Initialization::Storage); const auto firstInitializationAttempt =
mInitializationInfo.FirstInitializationAttempt(Initialization::Storage);
if (mStorageConnection) {
MOZ_ASSERT(firstInitializationAttempt.Recorded());
return NS_OK;
}
auto rv = [&firstInitializationAttempt, this]() -> nsresult {
const auto maybeExtraInfo = const auto maybeExtraInfo =
firstInitializationAttempt.Pending() firstInitializationAttempt.Pending()
? Some(ScopedLogExtraInfo{ ? Some(ScopedLogExtraInfo{
@ -6012,6 +5994,11 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
"dom::quota::FirstInitializationAttempt::Storage"_ns}) "dom::quota::FirstInitializationAttempt::Storage"_ns})
: Nothing{}; : Nothing{};
if (mStorageConnection) {
MOZ_ASSERT(firstInitializationAttempt.Recorded());
return NS_OK;
}
QM_TRY_INSPECT(const auto& storageFile, QM_NewLocalFile(mBasePath)); QM_TRY_INSPECT(const auto& storageFile, QM_NewLocalFile(mBasePath));
QM_TRY(storageFile->Append(mStorageName + kSQLiteSuffix)); QM_TRY(storageFile->Append(mStorageName + kSQLiteSuffix));
@ -6077,11 +6064,9 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
mStorageConnection = std::move(connection); mStorageConnection = std::move(connection);
return NS_OK; return NS_OK;
}(); };
firstInitializationAttempt.MaybeRecord(rv); return ExecuteInitialization(Initialization::Storage, innerFunc());
return rv;
} }
RefPtr<ClientDirectoryLock> QuotaManager::CreateDirectoryLock( RefPtr<ClientDirectoryLock> QuotaManager::CreateDirectoryLock(
@ -6111,16 +6096,14 @@ QuotaManager::EnsurePersistentOriginIsInitialized(
MOZ_ASSERT(aOriginMetadata.mPersistenceType == PERSISTENCE_TYPE_PERSISTENT); MOZ_ASSERT(aOriginMetadata.mPersistenceType == PERSISTENCE_TYPE_PERSISTENT);
MOZ_DIAGNOSTIC_ASSERT(mStorageConnection); MOZ_DIAGNOSTIC_ASSERT(mStorageConnection);
auto& originInitializationInfo = const auto innerFunc = [&aOriginMetadata, this]()
mInitializationInfo.MutableOriginInitializationInfoRef(
aOriginMetadata.mOrigin);
const auto firstInitializationAttempt =
originInitializationInfo.FirstInitializationAttempt(
OriginInitialization::PersistentOrigin);
auto res = [&firstInitializationAttempt, &aOriginMetadata, this]()
-> mozilla::Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult> { -> mozilla::Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult> {
const auto firstInitializationAttempt =
mInitializationInfo
.MutableOriginInitializationInfoRef(aOriginMetadata.mOrigin,
CreateIfNonExistent{})
.FirstInitializationAttempt(OriginInitialization::PersistentOrigin);
const auto maybeExtraInfo = const auto maybeExtraInfo =
firstInitializationAttempt.Pending() firstInitializationAttempt.Pending()
? Some(ScopedLogExtraInfo{ ? Some(ScopedLogExtraInfo{
@ -6133,6 +6116,7 @@ QuotaManager::EnsurePersistentOriginIsInitialized(
aOriginMetadata.mOrigin)); aOriginMetadata.mOrigin));
if (mInitializedOrigins.Contains(aOriginMetadata.mOrigin)) { if (mInitializedOrigins.Contains(aOriginMetadata.mOrigin)) {
MOZ_ASSERT(firstInitializationAttempt.Recorded());
return std::pair(std::move(directory), false); return std::pair(std::move(directory), false);
} }
@ -6169,11 +6153,11 @@ QuotaManager::EnsurePersistentOriginIsInitialized(
mInitializedOrigins.AppendElement(aOriginMetadata.mOrigin); mInitializedOrigins.AppendElement(aOriginMetadata.mOrigin);
return std::pair(std::move(directory), created); return std::pair(std::move(directory), created);
}(); };
firstInitializationAttempt.MaybeRecord(res.isOk() ? NS_OK : res.inspectErr()); return ExecuteOriginInitialization(aOriginMetadata.mOrigin,
OriginInitialization::PersistentOrigin,
return res; innerFunc());
} }
Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult> Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult>
@ -6184,19 +6168,14 @@ QuotaManager::EnsureTemporaryOriginIsInitialized(
MOZ_DIAGNOSTIC_ASSERT(mStorageConnection); MOZ_DIAGNOSTIC_ASSERT(mStorageConnection);
MOZ_DIAGNOSTIC_ASSERT(mTemporaryStorageInitialized); MOZ_DIAGNOSTIC_ASSERT(mTemporaryStorageInitialized);
auto& originInitializationInfo = const auto innerFunc = [&aPersistenceType, &aOriginMetadata, this]()
mInitializationInfo.MutableOriginInitializationInfoRef(
aOriginMetadata.mOrigin);
const auto firstInitializationAttempt =
originInitializationInfo.FirstInitializationAttempt(
OriginInitialization::TemporaryOrigin);
auto res = [&firstInitializationAttempt, &aPersistenceType, &aOriginMetadata,
this]()
-> mozilla::Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult> { -> mozilla::Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult> {
const auto maybeExtraInfo = const auto maybeExtraInfo =
firstInitializationAttempt.Pending() mInitializationInfo
.MutableOriginInitializationInfoRef(aOriginMetadata.mOrigin,
CreateIfNonExistent{})
.FirstInitializationAttemptPending(
OriginInitialization::TemporaryOrigin)
? Some(ScopedLogExtraInfo{ ? Some(ScopedLogExtraInfo{
ScopedLogExtraInfo::kTagContext, ScopedLogExtraInfo::kTagContext,
"dom::quota::FirstOriginInitializationAttempt::TemporaryOrigin"_ns}) "dom::quota::FirstOriginInitializationAttempt::TemporaryOrigin"_ns})
@ -6228,27 +6207,22 @@ QuotaManager::EnsureTemporaryOriginIsInitialized(
// file in next session in LoadQuotaFromCache. // file in next session in LoadQuotaFromCache.
return std::pair(std::move(directory), created); return std::pair(std::move(directory), created);
}(); };
firstInitializationAttempt.MaybeRecord(res.isOk() ? NS_OK : res.inspectErr()); return ExecuteOriginInitialization(aOriginMetadata.mOrigin,
OriginInitialization::TemporaryOrigin,
return res; innerFunc());
} }
nsresult QuotaManager::EnsureTemporaryStorageIsInitialized() { nsresult QuotaManager::EnsureTemporaryStorageIsInitialized() {
AssertIsOnIOThread(); AssertIsOnIOThread();
MOZ_DIAGNOSTIC_ASSERT(mStorageConnection); MOZ_DIAGNOSTIC_ASSERT(mStorageConnection);
const auto firstInitializationAttempt = const auto innerFunc = [this]() -> nsresult {
mInitializationInfo.FirstInitializationAttempt( const auto firstInitializationAttempt =
Initialization::TemporaryStorage); mInitializationInfo.FirstInitializationAttempt(
Initialization::TemporaryStorage);
if (mTemporaryStorageInitialized) {
MOZ_ASSERT(firstInitializationAttempt.Recorded());
return NS_OK;
}
auto rv = [&firstInitializationAttempt, this]() -> nsresult {
const auto maybeExtraInfo = const auto maybeExtraInfo =
firstInitializationAttempt.Pending() firstInitializationAttempt.Pending()
? Some(ScopedLogExtraInfo{ ? Some(ScopedLogExtraInfo{
@ -6256,6 +6230,11 @@ nsresult QuotaManager::EnsureTemporaryStorageIsInitialized() {
"dom::quota::FirstInitializationAttempt::TemporaryStorage"_ns}) "dom::quota::FirstInitializationAttempt::TemporaryStorage"_ns})
: Nothing{}; : Nothing{};
if (mTemporaryStorageInitialized) {
MOZ_ASSERT(firstInitializationAttempt.Recorded());
return NS_OK;
}
QM_TRY_INSPECT( QM_TRY_INSPECT(
const auto& storageDir, const auto& storageDir,
ToResultGet<nsCOMPtr<nsIFile>>(MOZ_SELECT_OVERLOAD(do_CreateInstance), ToResultGet<nsCOMPtr<nsIFile>>(MOZ_SELECT_OVERLOAD(do_CreateInstance),
@ -6283,7 +6262,7 @@ nsresult QuotaManager::EnsureTemporaryStorageIsInitialized() {
// limit calculation since available disk space is affected by existing data // limit calculation since available disk space is affected by existing data
// stored in temporary storage. So we need to increase it by the temporary // stored in temporary storage. So we need to increase it by the temporary
// storage size (that has been calculated in LoadQuota) before passing to // storage size (that has been calculated in LoadQuota) before passing to
// GetTemporaryStorageLimit.. // GetTemporaryStorageLimit.
mTemporaryStorageLimit = GetTemporaryStorageLimit( mTemporaryStorageLimit = GetTemporaryStorageLimit(
/* aAvailableSpaceBytes */ diskSpaceAvailable + mTemporaryStorageUsage); /* aAvailableSpaceBytes */ diskSpaceAvailable + mTemporaryStorageUsage);
@ -6294,11 +6273,9 @@ nsresult QuotaManager::EnsureTemporaryStorageIsInitialized() {
} }
return NS_OK; return NS_OK;
}(); };
firstInitializationAttempt.MaybeRecord(rv); return ExecuteInitialization(Initialization::TemporaryStorage, innerFunc());
return rv;
} }
void QuotaManager::ShutdownStorage() { void QuotaManager::ShutdownStorage() {
@ -7103,6 +7080,22 @@ int64_t QuotaManager::GenerateDirectoryLockId() {
return directorylockId; return directorylockId;
} }
nsresult QuotaManager::ExecuteInitialization(
const Initialization aInitialization, const nsresult aRv) {
return quota::ExecuteInitialization(mInitializationInfo, aInitialization,
aRv);
}
Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult>
QuotaManager::ExecuteOriginInitialization(
const nsACString& aOrigin, const OriginInitialization aInitialization,
Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult>&& aResult) {
return quota::ExecuteInitialization(
mInitializationInfo.MutableOriginInitializationInfoRef(
aOrigin, CreateIfNonExistent{}),
aInitialization, std::move(aResult));
}
/******************************************************************************* /*******************************************************************************
* Local class implementations * Local class implementations
******************************************************************************/ ******************************************************************************/

Просмотреть файл

@ -41,10 +41,6 @@ class FirstInitializationAttempts {
void Record(const nsresult aRv) const { void Record(const nsresult aRv) const {
mOwner.RecordFirstInitializationAttempt(mInitialization, aRv); mOwner.RecordFirstInitializationAttempt(mInitialization, aRv);
} }
void MaybeRecord(const nsresult aRv) const {
mOwner.MaybeRecordFirstInitializationAttempt(mInitialization, aRv);
}
}; };
FirstInitializationAttemptImpl FirstInitializationAttempt( FirstInitializationAttemptImpl FirstInitializationAttempt(
@ -65,15 +61,6 @@ class FirstInitializationAttempts {
void RecordFirstInitializationAttempt(const Initialization aInitialization, void RecordFirstInitializationAttempt(const Initialization aInitialization,
nsresult aRv); nsresult aRv);
void MaybeRecordFirstInitializationAttempt(
const Initialization aInitialization, const nsresult aRv) {
if (FirstInitializationAttemptRecorded(aInitialization)) {
return;
}
RecordFirstInitializationAttempt(aInitialization, aRv);
}
void ResetFirstInitializationAttempts() { void ResetFirstInitializationAttempts() {
mFirstInitializationAttempts = Initialization::None; mFirstInitializationAttempts = Initialization::None;
} }

Просмотреть файл

@ -22,15 +22,6 @@ void FirstInitializationAttempts<Initialization, StringGenerator>::
const nsresult aRv) { const nsresult aRv) {
MOZ_ASSERT(FirstInitializationAttemptPending(aInitialization)); MOZ_ASSERT(FirstInitializationAttemptPending(aInitialization));
// NS_ERROR_ABORT signals a non-fatal, recoverable problem during
// initialization. We do not want these kind of failures to count against our
// overall failure telemetry. Thus we just ignore this kind of failure and
// keep mFirstInitializationAttempts unflagged to stay ready to record a real
// failure on the next attempt.
if (aRv == NS_ERROR_ABORT) {
return;
}
mFirstInitializationAttempts |= aInitialization; mFirstInitializationAttempts |= aInitialization;
if constexpr (!std::is_same_v<StringGenerator, Nothing>) { if constexpr (!std::is_same_v<StringGenerator, Nothing>) {

Просмотреть файл

@ -13,6 +13,10 @@
#include "nsStringFwd.h" #include "nsStringFwd.h"
#include "nsTHashMap.h" #include "nsTHashMap.h"
namespace mozilla {
struct CreateIfNonExistent;
}
namespace mozilla::dom::quota { namespace mozilla::dom::quota {
enum class Initialization { enum class Initialization {
@ -58,7 +62,7 @@ class InitializationInfo
public: public:
OriginInitializationInfo& MutableOriginInitializationInfoRef( OriginInitializationInfo& MutableOriginInitializationInfoRef(
const nsACString& aOrigin) { const nsACString& aOrigin, const CreateIfNonExistent&) {
return mOriginInitializationInfos.LookupOrInsert(aOrigin); return mOriginInitializationInfos.LookupOrInsert(aOrigin);
} }

Просмотреть файл

@ -27,6 +27,7 @@
# include "mozilla/Variant.h" # include "mozilla/Variant.h"
#endif #endif
#include "mozilla/dom/QMResult.h" #include "mozilla/dom/QMResult.h"
#include "mozilla/dom/quota/FirstInitializationAttemptsImpl.h"
#include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/ipc/ProtocolUtils.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsDebug.h" #include "nsDebug.h"
@ -983,6 +984,8 @@ namespace mozilla {
class LogModule; class LogModule;
struct CreateIfNonExistent {};
struct NotOk {}; struct NotOk {};
// Allow MOZ_TRY/QM_TRY to handle `bool` values by wrapping them with OkIf. // Allow MOZ_TRY/QM_TRY to handle `bool` values by wrapping them with OkIf.
@ -1537,6 +1540,50 @@ auto CallWithDelayedRetriesIfAccessDenied(Func&& aFunc, uint32_t aMaxRetries,
} }
} }
template <typename Initialization, typename StringGenerator>
nsresult ExecuteInitialization(
FirstInitializationAttempts<Initialization, StringGenerator>&
aFirstInitializationAttempts,
const Initialization aInitialization, const nsresult aRv) {
// NS_ERROR_ABORT signals a non-fatal, recoverable problem during
// initialization. We do not want these kind of failures to count against our
// overall first initialization attempt telemetry. Thus we just ignore this
// kind of failure and keep aFirstInitializationAttempts unflagged to stay
// ready to record a real success or failure on the next attempt.
if (aRv == NS_ERROR_ABORT) {
return aRv;
}
if (!aFirstInitializationAttempts.FirstInitializationAttemptRecorded(
aInitialization)) {
aFirstInitializationAttempts.RecordFirstInitializationAttempt(
aInitialization, aRv);
}
return aRv;
}
// XXX Get rid of this special overload.
template <typename Initialization, typename StringGenerator>
Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult> ExecuteInitialization(
FirstInitializationAttempts<Initialization, StringGenerator>&
aFirstInitializationAttempts,
const Initialization aInitialization,
Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult>&& aResult) {
// See the comment above for the NS_ERROR_ABORT special case.
if (aResult.isErr() && aResult.inspectErr() == NS_ERROR_ABORT) {
return std::move(aResult);
}
if (!aFirstInitializationAttempts.FirstInitializationAttemptRecorded(
aInitialization)) {
aFirstInitializationAttempts.RecordFirstInitializationAttempt(
aInitialization, aResult.isOk() ? NS_OK : aResult.inspectErr());
}
return std::move(aResult);
}
} // namespace quota } // namespace quota
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -548,6 +548,14 @@ class QuotaManager final : public BackgroundThreadObject {
void MaybeRecordShutdownStep(Maybe<Client::Type> aClientType, void MaybeRecordShutdownStep(Maybe<Client::Type> aClientType,
const nsACString& aStepDescription); const nsACString& aStepDescription);
nsresult ExecuteInitialization(Initialization aInitialization, nsresult aRv);
// XXX Generalize this method.
Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult>
ExecuteOriginInitialization(
const nsACString& aOrigin, const OriginInitialization aInitialization,
Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult>&& aResult);
template <typename Iterator> template <typename Iterator>
static void MaybeInsertNonPersistedOriginInfos( static void MaybeInsertNonPersistedOriginInfos(
Iterator aDest, const RefPtr<GroupInfo>& aTemporaryGroupInfo, Iterator aDest, const RefPtr<GroupInfo>& aTemporaryGroupInfo,