Bug 1726809 - Simplify QuotaManager::GetOrCreate and intermediate state of opening QuotaManager; r=dom-storage-reviewers,janv

Differential Revision: https://phabricator.services.mozilla.com/D131592
This commit is contained in:
Haiyang Xu 2021-11-26 09:20:57 +00:00
Родитель f8f4abb939
Коммит a12fd4fda6
6 изменённых файлов: 50 добавлений и 257 удалений

58
dom/cache/Context.cpp поставляемый
Просмотреть файл

@ -139,8 +139,6 @@ class Context::QuotaInitRunnable final : public nsIRunnable,
mInitAction->CancelOnInitiatingThread();
}
void OpenDirectory();
// OpenDirectoryListener methods
virtual void DirectoryLockAcquired(DirectoryLock* aLock) override;
@ -180,7 +178,6 @@ class Context::QuotaInitRunnable final : public nsIRunnable,
STATE_INIT,
STATE_GET_INFO,
STATE_CREATE_QUOTA_MANAGER,
STATE_OPEN_DIRECTORY,
STATE_WAIT_FOR_DIRECTORY_LOCK,
STATE_ENSURE_ORIGIN_INITIALIZED,
STATE_RUN_ON_TARGET,
@ -226,25 +223,6 @@ class Context::QuotaInitRunnable final : public nsIRunnable,
NS_DECL_NSIRUNNABLE
};
void Context::QuotaInitRunnable::OpenDirectory() {
NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
MOZ_DIAGNOSTIC_ASSERT(mState == STATE_CREATE_QUOTA_MANAGER ||
mState == STATE_OPEN_DIRECTORY);
MOZ_DIAGNOSTIC_ASSERT(QuotaManager::Get());
RefPtr<DirectoryLock> directoryLock =
QuotaManager::Get()->CreateDirectoryLock(PERSISTENCE_TYPE_DEFAULT,
*mDirectoryMetadata,
quota::Client::DOMCACHE,
/* aExclusive */ false);
// DirectoryLock::Acquire() will hold a reference to us as a listener. We will
// then get DirectoryLockAcquired() on the owning thread when it is safe to
// access our storage directory.
mState = STATE_WAIT_FOR_DIRECTORY_LOCK;
directoryLock->Acquire(this);
}
void Context::QuotaInitRunnable::DirectoryLockAcquired(DirectoryLock* aLock) {
NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
MOZ_DIAGNOSTIC_ASSERT(aLock);
@ -302,11 +280,6 @@ NS_IMPL_ISUPPORTS(mozilla::dom::cache::Context::QuotaInitRunnable, nsIRunnable);
// +----------+-----------+ |
// | |
// +----------v-----------+ |
// | OpenDirectory | Resolve(error) |
// | (Orig Thread) +-----------------+
// +----------+-----------+ |
// | |
// +----------v-----------+ |
// | WaitForDirectoryLock | Resolve(error) |
// | (Orig Thread) +-----------------+
// +----------+-----------+ |
@ -379,25 +352,24 @@ Context::QuotaInitRunnable::Run() {
break;
}
if (QuotaManager::Get()) {
OpenDirectory();
return NS_OK;
}
QM_TRY(QuotaManager::EnsureCreated(), QM_PROPAGATE,
[&resolver](const auto rv) { resolver->Resolve(rv); });
mState = STATE_OPEN_DIRECTORY;
QuotaManager::GetOrCreate(this);
break;
}
// ----------------------------------
case STATE_OPEN_DIRECTORY: {
NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
MOZ_DIAGNOSTIC_ASSERT(QuotaManager::Get());
if (NS_WARN_IF(!QuotaManager::Get())) {
resolver->Resolve(NS_ERROR_FAILURE);
break;
}
// Open directory
RefPtr<DirectoryLock> directoryLock =
QuotaManager::Get()->CreateDirectoryLock(PERSISTENCE_TYPE_DEFAULT,
*mDirectoryMetadata,
quota::Client::DOMCACHE,
/* aExclusive */ false);
// DirectoryLock::Acquire() will hold a reference to us as a listener. We
// will then get DirectoryLockAcquired() on the owning thread when it is
// safe to access our storage directory.
mState = STATE_WAIT_FOR_DIRECTORY_LOCK;
directoryLock->Acquire(this);
OpenDirectory();
break;
}
// ----------------------------------

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

@ -3098,17 +3098,11 @@ class FactoryOp
// if permission is granted.
PermissionRetry,
// Opening directory or initializing quota manager on the PBackground
// thread. Next step is either DirectoryOpenPending if quota manager is
// already initialized or QuotaManagerPending if quota manager needs to be
// initialized.
// Ensuring quota manager is created and opening directory on the
// PBackground thread. Next step is either SendingResults if quota manager
// is not available or DirectoryOpenPending if quota manager is available.
FinishOpen,
// Waiting for quota manager initialization to complete on the PBackground
// thread. Next step is either SendingResults if initialization failed or
// DirectoryOpenPending if initialization succeeded.
QuotaManagerPending,
// Waiting for directory open allowed on the PBackground thread. The next
// step is either SendingResults if directory lock failed to acquire, or
// DatabaseOpenPending if directory lock is acquired.
@ -3289,10 +3283,6 @@ class FactoryOp
nsresult FinishOpen();
nsresult QuotaManagerOpen();
nsresult OpenDirectory();
// Test whether this FactoryOp needs to wait for the given op.
bool MustWaitFor(const FactoryOp& aExistingOp);
};
@ -15271,10 +15261,6 @@ void FactoryOp::StringifyState(nsACString& aResult) const {
aResult.AppendLiteral("FinishOpen");
return;
case State::QuotaManagerPending:
aResult.AppendLiteral("QuotaManagerPending");
return;
case State::DirectoryOpenPending:
aResult.AppendLiteral("DirectoryOpenPending");
return;
@ -15776,6 +15762,8 @@ nsresult FactoryOp::FinishOpen() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::FinishOpen);
MOZ_ASSERT(!mContentParent);
MOZ_ASSERT(!mOriginMetadata.mOrigin.IsEmpty());
MOZ_ASSERT(!mDirectoryLock);
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
IsActorDestroyed()) {
@ -15783,37 +15771,7 @@ nsresult FactoryOp::FinishOpen() {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (QuotaManager::Get()) {
QM_TRY(MOZ_TO_RESULT(OpenDirectory()));
return NS_OK;
}
mState = State::QuotaManagerPending;
QuotaManager::GetOrCreate(this);
return NS_OK;
}
nsresult FactoryOp::QuotaManagerOpen() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::QuotaManagerPending);
QM_TRY(OkIf(QuotaManager::Get()), NS_ERROR_FAILURE);
QM_TRY(MOZ_TO_RESULT(OpenDirectory()));
return NS_OK;
}
nsresult FactoryOp::OpenDirectory() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::FinishOpen ||
mState == State::QuotaManagerPending);
MOZ_ASSERT(!mOriginMetadata.mOrigin.IsEmpty());
MOZ_ASSERT(!mDirectoryLock);
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
MOZ_ASSERT(QuotaManager::Get());
QM_TRY(QuotaManager::EnsureCreated());
const PersistenceType persistenceType =
mCommonParams.metadata().persistenceType();
@ -15841,6 +15799,7 @@ nsresult FactoryOp::OpenDirectory() {
QM_TRY_RETURN(MOZ_TO_RESULT_INVOKE_TYPED(nsString, dbFile, GetPath));
}()));
// Open directory
RefPtr<DirectoryLock> directoryLock = quotaManager->CreateDirectoryLock(
persistenceType, mOriginMetadata, Client::IDB,
/* aExclusive */ false);
@ -15906,10 +15865,6 @@ FactoryOp::Run() {
QM_TRY(MOZ_TO_RESULT(FinishOpen()), NS_OK, handleError);
break;
case State::QuotaManagerPending:
QM_TRY(MOZ_TO_RESULT(QuotaManagerOpen()), NS_OK, handleError);
break;
case State::DatabaseOpenPending:
QM_TRY(MOZ_TO_RESULT(DatabaseOpen()), NS_OK, handleError);
break;

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

@ -2129,19 +2129,13 @@ class PrepareDatastoreOp
// the PBackground thread. Next step is PreparationPending.
CheckClosingDatastore,
// Opening directory or initializing quota manager on the PBackground
// thread. Next step is either DirectoryOpenPending if quota manager is
// already initialized or QuotaManagerPending if quota manager needs to be
// initialized.
// Ensuring quota manager is created and opening directory on the
// PBackground thread. Next step is either SendingResults if quota manager
// is not available or DirectoryOpenPending if quota manager is available.
// If a datastore already exists for given origin then the next state is
// SendingReadyMessage.
PreparationPending,
// Waiting for quota manager initialization to complete on the PBackground
// thread. Next step is either SendingReadyMessage if initialization failed
// or DirectoryOpenPending if initialization succeeded.
QuotaManagerPending,
// Waiting for directory open allowed on the PBackground thread. The next
// step is either SendingReadyMessage if directory lock failed to acquire,
// or DatabaseWorkOpen if directory lock is acquired.
@ -2247,10 +2241,6 @@ class PrepareDatastoreOp
nsresult BeginDatastorePreparation();
nsresult QuotaManagerOpen();
nsresult OpenDirectory();
void SendToIOThread();
nsresult DatabaseWork();
@ -6437,10 +6427,6 @@ void PrepareDatastoreOp::StringifyNestedState(nsACString& aResult) const {
aResult.AppendLiteral("PreparationPending");
return;
case NestedState::QuotaManagerPending:
aResult.AppendLiteral("QuotaManagerPending");
return;
case NestedState::DirectoryOpenPending:
aResult.AppendLiteral("DirectoryOpenPending");
return;
@ -6704,6 +6690,8 @@ nsresult PrepareDatastoreOp::BeginDatastorePreparationInternal() {
MOZ_ASSERT(mNestedState == NestedState::PreparationPending);
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
MOZ_ASSERT(MayProceed());
MOZ_ASSERT(OriginIsKnown());
MOZ_ASSERT(!mDirectoryLock);
if ((mDatastore = GetDatastore(Origin()))) {
MOZ_ASSERT(!mDatastore->IsClosed());
@ -6715,49 +6703,9 @@ nsresult PrepareDatastoreOp::BeginDatastorePreparationInternal() {
return NS_OK;
}
if (QuotaManager::Get()) {
nsresult rv = OpenDirectory();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
mNestedState = NestedState::QuotaManagerPending;
QuotaManager::GetOrCreate(this);
return NS_OK;
}
nsresult PrepareDatastoreOp::QuotaManagerOpen() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::Nesting);
MOZ_ASSERT(mNestedState == NestedState::QuotaManagerPending);
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
!MayProceed()) {
return NS_ERROR_ABORT;
}
QM_TRY(OkIf(QuotaManager::Get()), NS_ERROR_FAILURE);
QM_TRY(MOZ_TO_RESULT(OpenDirectory()));
return NS_OK;
}
nsresult PrepareDatastoreOp::OpenDirectory() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::Nesting);
MOZ_ASSERT(mNestedState == NestedState::PreparationPending ||
mNestedState == NestedState::QuotaManagerPending);
MOZ_ASSERT(OriginIsKnown());
MOZ_ASSERT(!mDirectoryLock);
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
MOZ_ASSERT(MayProceed());
MOZ_ASSERT(QuotaManager::Get());
QM_TRY(QuotaManager::EnsureCreated());
// Open directory
mPendingDirectoryLock = QuotaManager::Get()->CreateDirectoryLock(
PERSISTENCE_TYPE_DEFAULT, mOriginMetadata,
mozilla::dom::quota::Client::LS,
@ -7264,10 +7212,6 @@ nsresult PrepareDatastoreOp::NestedRun() {
rv = BeginDatastorePreparation();
break;
case NestedState::QuotaManagerPending:
rv = QuotaManagerOpen();
break;
case NestedState::DatabaseWorkOpen:
rv = DatabaseWork();
break;

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

@ -1039,9 +1039,6 @@ class OriginOperationBase : public BackgroundThreadObject, public Runnable {
// Not yet run.
State_Initial,
// Running quota manager initialization on the owning thread.
State_CreatingQuotaManager,
// Running on the owning thread in the listener for OpenDirectory.
State_DirectoryOpenPending,
@ -1105,9 +1102,6 @@ class OriginOperationBase : public BackgroundThreadObject, public Runnable {
void AdvanceState() {
switch (mState) {
case State_Initial:
mState = State_CreatingQuotaManager;
return;
case State_CreatingQuotaManager:
mState = State_DirectoryOpenPending;
return;
case State_DirectoryOpenPending:
@ -1142,8 +1136,6 @@ class OriginOperationBase : public BackgroundThreadObject, public Runnable {
nsresult FinishInit();
nsresult QuotaManagerOpen();
nsresult DirectoryWork();
};
@ -3367,12 +3359,10 @@ QuotaManager::GetOrCreate() {
return WrapMovingNotNullUnchecked(std::move(instance));
}
void QuotaManager::GetOrCreate(nsIRunnable* aCallback) {
Result<Ok, nsresult> QuotaManager::EnsureCreated() {
AssertIsOnBackgroundThread();
Unused << GetOrCreate();
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(aCallback));
QM_TRY_RETURN(GetOrCreate().map([](const auto& res) { return Ok{}; }))
}
// static
@ -7697,11 +7687,6 @@ OriginOperationBase::Run() {
break;
}
case State_CreatingQuotaManager: {
rv = QuotaManagerOpen();
break;
}
case State_DirectoryOpenPending: {
rv = DirectoryOpen();
break;
@ -7765,23 +7750,8 @@ nsresult OriginOperationBase::Init() {
return NS_ERROR_ABORT;
}
AdvanceState();
if (mNeedsQuotaManagerInit && !QuotaManager::Get()) {
QuotaManager::GetOrCreate(this);
} else {
Open();
}
return NS_OK;
}
nsresult OriginOperationBase::QuotaManagerOpen() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State_CreatingQuotaManager);
if (NS_WARN_IF(!QuotaManager::Get())) {
return NS_ERROR_FAILURE;
if (mNeedsQuotaManagerInit) {
QM_TRY(QuotaManager::EnsureCreated());
}
Open();
@ -7871,7 +7841,7 @@ RefPtr<DirectoryLock> NormalOriginOperationBase::CreateDirectoryLock() {
void NormalOriginOperationBase::Open() {
AssertIsOnOwningThread();
MOZ_ASSERT(GetState() == State_CreatingQuotaManager);
MOZ_ASSERT(GetState() == State_Initial);
MOZ_ASSERT(QuotaManager::Get());
AdvanceState();
@ -8466,15 +8436,10 @@ mozilla::ipc::IPCResult Quota::RecvStartIdleMaintenance() {
return IPC_OK();
}
QuotaManager* quotaManager = QuotaManager::Get();
if (!quotaManager) {
nsCOMPtr<nsIRunnable> callback =
NewRunnableMethod("dom::quota::Quota::StartIdleMaintenance", this,
&Quota::StartIdleMaintenance);
QM_TRY(QuotaManager::EnsureCreated(), IPC_OK());
QuotaManager::GetOrCreate(callback);
return IPC_OK();
}
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
quotaManager->StartIdleMaintenance();

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

@ -106,8 +106,7 @@ class QuotaManager final : public BackgroundThreadObject {
static Result<MovingNotNull<RefPtr<QuotaManager>>, nsresult> GetOrCreate();
// TODO: Remove this overload once all clients use the synchronous GetOrCreate
static void GetOrCreate(nsIRunnable* aCallback);
static Result<Ok, nsresult> EnsureCreated();
// Returns a non-owning reference.
static QuotaManager* Get();

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

@ -315,17 +315,11 @@ class OpenOp final : public ConnectionOperationBase,
// Next step is FinishOpen.
Initial,
// Opening directory or initializing quota manager on the PBackground
// thread. Next step is either DirectoryOpenPending if quota manager is
// already initialized or QuotaManagerPending if quota manager needs to be
// initialized.
// Ensuring quota manager is created and opening directory on the
// PBackground thread. Next step is either SendingResults if quota manager
// is not available or DirectoryOpenPending if quota manager is available.
FinishOpen,
// Waiting for quota manager initialization to complete on the PBackground
// thread. Next step is either SendingResults if initialization failed or
// DirectoryOpenPending if initialization succeeded.
QuotaManagerPending,
// Waiting for directory open allowed on the PBackground thread. The next
// step is either SendingResults if directory lock failed to acquire, or
// DatabaseWorkOpen if directory lock is acquired.
@ -363,10 +357,6 @@ class OpenOp final : public ConnectionOperationBase,
nsresult FinishOpen();
nsresult QuotaManagerOpen();
nsresult OpenDirectory();
nsresult SendToIOThread();
nsresult DatabaseWork();
@ -1135,8 +1125,15 @@ nsresult OpenOp::Open() {
nsresult OpenOp::FinishOpen() {
AssertIsOnOwningThread();
MOZ_ASSERT(!mOriginMetadata.mOrigin.IsEmpty());
MOZ_ASSERT(!mDirectoryLock);
MOZ_ASSERT(mState == State::FinishOpen);
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
IsActorDestroyed()) {
return NS_ERROR_ABORT;
}
if (gOpenConnections) {
for (const auto& connection : *gOpenConnections) {
if (connection->Origin() == mOriginMetadata.mOrigin &&
@ -1146,44 +1143,9 @@ nsresult OpenOp::FinishOpen() {
}
}
if (QuotaManager::Get()) {
nsresult rv = OpenDirectory();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
QM_TRY(QuotaManager::EnsureCreated());
return NS_OK;
}
mState = State::QuotaManagerPending;
QuotaManager::GetOrCreate(this);
return NS_OK;
}
nsresult OpenOp::QuotaManagerOpen() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::QuotaManagerPending);
if (NS_WARN_IF(!QuotaManager::Get())) {
return NS_ERROR_FAILURE;
}
nsresult rv = OpenDirectory();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult OpenOp::OpenDirectory() {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::FinishOpen ||
mState == State::QuotaManagerPending);
MOZ_ASSERT(!mOriginMetadata.mOrigin.IsEmpty());
MOZ_ASSERT(!mDirectoryLock);
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
// Open the directory
MOZ_ASSERT(QuotaManager::Get());
RefPtr<DirectoryLock> directoryLock =
@ -1411,10 +1373,6 @@ OpenOp::Run() {
rv = FinishOpen();
break;
case State::QuotaManagerPending:
rv = QuotaManagerOpen();
break;
case State::DatabaseWorkOpen:
rv = DatabaseWork();
break;