зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1749504 - Introduce a new method QuotaManager::OpenStorageDirectory; r=dom-storage-reviewers,jstutte
Quota manager origin operations and IndexedDB database maintenance currently call QuotaManager::CreateDirectoryLockInternal and DirectoryLock::Acquire to acquire a universal directory lock. Once that's all successfully done, they bounce to the QuotaManager IO thread where they synchronously call QuotaManager::EnsureStorageIsInitializedInternal. The new QuotaManager::OpenStorageDirectory method wraps all this complexity, so consumers can just obtain a universal directory lock when all required storage initialization is done. Changes done in this patch: - added QuotaManager::OpenStorageDirectory - added tests for the new method Differential Revision: https://phabricator.services.mozilla.com/D186134
This commit is contained in:
Родитель
fb80484f6c
Коммит
9fd6f9cf81
|
@ -4993,6 +4993,79 @@ nsresult QuotaManager::EnsureStorageIsInitializedInternal() {
|
||||||
"dom::quota::FirstInitializationAttempt::Storage"_ns, innerFunc);
|
"dom::quota::FirstInitializationAttempt::Storage"_ns, innerFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefPtr<UniversalDirectoryLockPromise> QuotaManager::OpenStorageDirectory(
|
||||||
|
const Nullable<PersistenceType>& aPersistenceType,
|
||||||
|
const OriginScope& aOriginScope, const Nullable<Client::Type>& aClientType,
|
||||||
|
bool aExclusive,
|
||||||
|
Maybe<RefPtr<UniversalDirectoryLock>&> aPendingDirectoryLockOut) {
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
RefPtr<UniversalDirectoryLock> storageDirectoryLock;
|
||||||
|
|
||||||
|
RefPtr<BoolPromise> storageDirectoryLockPromise;
|
||||||
|
|
||||||
|
if (mStorageInitialized && !mShutdownStorageOpCount) {
|
||||||
|
storageDirectoryLockPromise = BoolPromise::CreateAndResolve(true, __func__);
|
||||||
|
} else {
|
||||||
|
storageDirectoryLock = CreateDirectoryLockInternal(
|
||||||
|
Nullable<PersistenceType>(), OriginScope::FromNull(),
|
||||||
|
Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false);
|
||||||
|
|
||||||
|
storageDirectoryLockPromise = storageDirectoryLock->Acquire();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<UniversalDirectoryLock> universalDirectoryLock =
|
||||||
|
CreateDirectoryLockInternal(aPersistenceType, aOriginScope, aClientType,
|
||||||
|
aExclusive);
|
||||||
|
|
||||||
|
RefPtr<BoolPromise> universalDirectoryLockPromise =
|
||||||
|
universalDirectoryLock->Acquire();
|
||||||
|
|
||||||
|
if (aPendingDirectoryLockOut.isSome()) {
|
||||||
|
aPendingDirectoryLockOut.ref() = universalDirectoryLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
return storageDirectoryLockPromise
|
||||||
|
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[self = RefPtr(this),
|
||||||
|
storageDirectoryLock = std::move(storageDirectoryLock)](
|
||||||
|
const BoolPromise::ResolveOrRejectValue& aValue) mutable {
|
||||||
|
if (aValue.IsReject()) {
|
||||||
|
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!storageDirectoryLock) {
|
||||||
|
return BoolPromise::CreateAndResolve(true, __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self->InitializeStorage(std::move(storageDirectoryLock));
|
||||||
|
})
|
||||||
|
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[universalDirectoryLockPromise =
|
||||||
|
std::move(universalDirectoryLockPromise)](
|
||||||
|
const BoolPromise::ResolveOrRejectValue& aValue) mutable {
|
||||||
|
if (aValue.IsReject()) {
|
||||||
|
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(universalDirectoryLockPromise);
|
||||||
|
})
|
||||||
|
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[universalDirectoryLock = std::move(universalDirectoryLock)](
|
||||||
|
const BoolPromise::ResolveOrRejectValue& aValue) mutable {
|
||||||
|
if (aValue.IsReject()) {
|
||||||
|
return UniversalDirectoryLockPromise::CreateAndReject(
|
||||||
|
aValue.RejectValue(), __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return UniversalDirectoryLockPromise::CreateAndResolve(
|
||||||
|
std::move(universalDirectoryLock), __func__);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<ClientDirectoryLockPromise> QuotaManager::OpenClientDirectory(
|
RefPtr<ClientDirectoryLockPromise> QuotaManager::OpenClientDirectory(
|
||||||
const ClientMetadata& aClientMetadata,
|
const ClientMetadata& aClientMetadata,
|
||||||
Maybe<RefPtr<ClientDirectoryLock>&> aPendingDirectoryLockOut) {
|
Maybe<RefPtr<ClientDirectoryLock>&> aPendingDirectoryLockOut) {
|
||||||
|
|
|
@ -50,9 +50,12 @@ using BoolResponseResolver = std::function<void(const BoolResponse&)>;
|
||||||
namespace dom::quota {
|
namespace dom::quota {
|
||||||
|
|
||||||
class ClientDirectoryLock;
|
class ClientDirectoryLock;
|
||||||
|
class UniversalDirectoryLock;
|
||||||
|
|
||||||
using ClientDirectoryLockPromise =
|
using ClientDirectoryLockPromise =
|
||||||
MozPromise<RefPtr<ClientDirectoryLock>, nsresult, true>;
|
MozPromise<RefPtr<ClientDirectoryLock>, nsresult, true>;
|
||||||
|
using UniversalDirectoryLockPromise =
|
||||||
|
MozPromise<RefPtr<UniversalDirectoryLock>, nsresult, true>;
|
||||||
|
|
||||||
} // namespace dom::quota
|
} // namespace dom::quota
|
||||||
|
|
||||||
|
|
|
@ -258,6 +258,13 @@ class QuotaManager final : public BackgroundThreadObject {
|
||||||
|
|
||||||
Result<OriginMetadata, nsresult> GetOriginMetadata(nsIFile* aDirectory);
|
Result<OriginMetadata, nsresult> GetOriginMetadata(nsIFile* aDirectory);
|
||||||
|
|
||||||
|
RefPtr<UniversalDirectoryLockPromise> OpenStorageDirectory(
|
||||||
|
const Nullable<PersistenceType>& aPersistenceType,
|
||||||
|
const OriginScope& aOriginScope,
|
||||||
|
const Nullable<Client::Type>& aClientType, bool aExclusive,
|
||||||
|
Maybe<RefPtr<UniversalDirectoryLock>&> aPendingDirectoryLockOut =
|
||||||
|
Nothing());
|
||||||
|
|
||||||
// This is the main entry point into the QuotaManager API.
|
// This is the main entry point into the QuotaManager API.
|
||||||
// Any storage API implementation (quota client) that participates in
|
// Any storage API implementation (quota client) that participates in
|
||||||
// centralized quota and storage handling should call this method to get
|
// centralized quota and storage handling should call this method to get
|
||||||
|
|
|
@ -21,6 +21,414 @@ class TestQuotaManager : public QuotaManagerDependencyFixture {
|
||||||
static void TearDownTestCase() { ASSERT_NO_FATAL_FAILURE(ShutdownFixture()); }
|
static void TearDownTestCase() { ASSERT_NO_FATAL_FAILURE(ShutdownFixture()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Test OpenStorageDirectory when an opening of the storage directory is
|
||||||
|
// already ongoing and storage shutdown is scheduled after that.
|
||||||
|
TEST_F(TestQuotaManager, OpenStorageDirectory_OngoingWithScheduledShutdown) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||||
|
|
||||||
|
PerformOnBackgroundThread([]() {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
RefPtr<UniversalDirectoryLock> directoryLock;
|
||||||
|
|
||||||
|
nsTArray<RefPtr<BoolPromise>> promises;
|
||||||
|
|
||||||
|
promises.AppendElement(
|
||||||
|
quotaManager
|
||||||
|
->OpenStorageDirectory(
|
||||||
|
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||||
|
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false)
|
||||||
|
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&directoryLock](
|
||||||
|
UniversalDirectoryLockPromise::ResolveOrRejectValue&&
|
||||||
|
aValue) {
|
||||||
|
if (aValue.IsReject()) {
|
||||||
|
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
[&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }();
|
||||||
|
|
||||||
|
directoryLock = std::move(aValue.ResolveValue());
|
||||||
|
|
||||||
|
return BoolPromise::CreateAndResolve(true, __func__);
|
||||||
|
})
|
||||||
|
->Then(quotaManager->IOThread(), __func__,
|
||||||
|
[](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||||
|
if (aValue.IsReject()) {
|
||||||
|
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
[]() {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
ASSERT_TRUE(
|
||||||
|
quotaManager->IsStorageInitializedInternal());
|
||||||
|
}();
|
||||||
|
|
||||||
|
return BoolPromise::CreateAndResolve(true, __func__);
|
||||||
|
})
|
||||||
|
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&directoryLock](
|
||||||
|
const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||||
|
directoryLock = nullptr;
|
||||||
|
|
||||||
|
if (aValue.IsReject()) {
|
||||||
|
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoolPromise::CreateAndResolve(true, __func__);
|
||||||
|
}));
|
||||||
|
promises.AppendElement(quotaManager->ShutdownStorage());
|
||||||
|
promises.AppendElement(
|
||||||
|
quotaManager
|
||||||
|
->OpenStorageDirectory(
|
||||||
|
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||||
|
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false)
|
||||||
|
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||||
|
aValue) {
|
||||||
|
if (aValue.IsReject()) {
|
||||||
|
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoolPromise::CreateAndResolve(true, __func__);
|
||||||
|
}));
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
BoolPromise::All(GetCurrentSerialEventTarget(), promises)
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&done](const CopyableTArray<bool>& aResolveValues) {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
},
|
||||||
|
[&done](nsresult aRejectValue) {
|
||||||
|
ASSERT_TRUE(false);
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test OpenStorageDirectory when an opening of the storage directory is
|
||||||
|
// already ongoing and an exclusive directory lock is requested after that.
|
||||||
|
TEST_F(TestQuotaManager,
|
||||||
|
OpenStorageDirectory_OngoingWithExclusiveDirectoryLock) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||||
|
|
||||||
|
PerformOnBackgroundThread([]() {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
RefPtr<UniversalDirectoryLock> directoryLock =
|
||||||
|
quotaManager->CreateDirectoryLockInternal(Nullable<PersistenceType>(),
|
||||||
|
OriginScope::FromNull(),
|
||||||
|
Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ true);
|
||||||
|
|
||||||
|
nsTArray<RefPtr<BoolPromise>> promises;
|
||||||
|
|
||||||
|
promises.AppendElement(
|
||||||
|
quotaManager
|
||||||
|
->OpenStorageDirectory(
|
||||||
|
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||||
|
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false)
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&directoryLock](
|
||||||
|
const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||||
|
aValue) {
|
||||||
|
directoryLock = nullptr;
|
||||||
|
|
||||||
|
if (aValue.IsReject()) {
|
||||||
|
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoolPromise::CreateAndResolve(true, __func__);
|
||||||
|
}));
|
||||||
|
promises.AppendElement(directoryLock->Acquire());
|
||||||
|
promises.AppendElement(
|
||||||
|
quotaManager
|
||||||
|
->OpenStorageDirectory(
|
||||||
|
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||||
|
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false)
|
||||||
|
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||||
|
aValue) {
|
||||||
|
if (aValue.IsReject()) {
|
||||||
|
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoolPromise::CreateAndResolve(true, __func__);
|
||||||
|
}));
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
BoolPromise::All(GetCurrentSerialEventTarget(), promises)
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&done](const CopyableTArray<bool>& aResolveValues) {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
},
|
||||||
|
[&done](nsresult aRejectValue) {
|
||||||
|
ASSERT_TRUE(false);
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test OpenStorageDirectory when an opening of the storage directory already
|
||||||
|
// finished.
|
||||||
|
TEST_F(TestQuotaManager, OpenStorageDirectory_Finished) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||||
|
|
||||||
|
PerformOnBackgroundThread([]() {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
quotaManager
|
||||||
|
->OpenStorageDirectory(
|
||||||
|
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||||
|
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false)
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&done](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||||
|
aValue) {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||||
|
|
||||||
|
done = false;
|
||||||
|
|
||||||
|
quotaManager
|
||||||
|
->OpenStorageDirectory(
|
||||||
|
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||||
|
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false)
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&done](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||||
|
aValue) {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test OpenStorageDirectory when an opening of the storage directory already
|
||||||
|
// finished but storage shutdown has just been scheduled.
|
||||||
|
TEST_F(TestQuotaManager, OpenStorageDirectory_FinishedWithScheduledShutdown) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||||
|
|
||||||
|
PerformOnBackgroundThread([]() {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
quotaManager
|
||||||
|
->OpenStorageDirectory(
|
||||||
|
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||||
|
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false)
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&done](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||||
|
aValue) {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||||
|
|
||||||
|
nsTArray<RefPtr<BoolPromise>> promises;
|
||||||
|
|
||||||
|
promises.AppendElement(quotaManager->ShutdownStorage());
|
||||||
|
promises.AppendElement(
|
||||||
|
quotaManager
|
||||||
|
->OpenStorageDirectory(
|
||||||
|
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||||
|
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false)
|
||||||
|
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||||
|
aValue) {
|
||||||
|
if (aValue.IsReject()) {
|
||||||
|
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoolPromise::CreateAndResolve(true, __func__);
|
||||||
|
}));
|
||||||
|
|
||||||
|
done = false;
|
||||||
|
|
||||||
|
BoolPromise::All(GetCurrentSerialEventTarget(), promises)
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&done](const CopyableTArray<bool>& aResolveValues) {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
},
|
||||||
|
[&done](nsresult aRejectValue) {
|
||||||
|
ASSERT_TRUE(false);
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test OpenStorageDirectory when an opening of the storage directory already
|
||||||
|
// finished and an exclusive client directory lock for a non-overlapping
|
||||||
|
// origin is acquired in between.
|
||||||
|
TEST_F(TestQuotaManager,
|
||||||
|
OpenStorageDirectory_FinishedWithExclusiveClientDirectoryLock) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||||
|
|
||||||
|
PerformOnBackgroundThread([]() {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
quotaManager
|
||||||
|
->OpenStorageDirectory(
|
||||||
|
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||||
|
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false)
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&done](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||||
|
aValue) {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||||
|
|
||||||
|
RefPtr<ClientDirectoryLock> directoryLock =
|
||||||
|
quotaManager->CreateDirectoryLock(GetTestClientMetadata(),
|
||||||
|
/* aExclusive */ true);
|
||||||
|
|
||||||
|
done = false;
|
||||||
|
|
||||||
|
directoryLock->Acquire()->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&done](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||||
|
|
||||||
|
done = false;
|
||||||
|
|
||||||
|
quotaManager
|
||||||
|
->OpenStorageDirectory(
|
||||||
|
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||||
|
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false)
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[&done](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||||
|
aValue) {
|
||||||
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
|
ASSERT_TRUE(quotaManager);
|
||||||
|
|
||||||
|
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||||
|
}
|
||||||
|
|
||||||
// Test OpenClientDirctory when an opening of a client directory is already
|
// Test OpenClientDirctory when an opening of a client directory is already
|
||||||
// ongoing and storage shutdown is scheduled after that.
|
// ongoing and storage shutdown is scheduled after that.
|
||||||
TEST_F(TestQuotaManager, OpenClientDirectory_OngoingWithScheduledShutdown) {
|
TEST_F(TestQuotaManager, OpenClientDirectory_OngoingWithScheduledShutdown) {
|
||||||
|
@ -47,6 +455,8 @@ TEST_F(TestQuotaManager, OpenClientDirectory_OngoingWithScheduledShutdown) {
|
||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }();
|
||||||
|
|
||||||
directoryLock = std::move(aValue.ResolveValue());
|
directoryLock = std::move(aValue.ResolveValue());
|
||||||
|
|
||||||
return BoolPromise::CreateAndResolve(true, __func__);
|
return BoolPromise::CreateAndResolve(true, __func__);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче