From da0de838c2ebde1b8de7c470716fdc2782d26973 Mon Sep 17 00:00:00 2001 From: Jan Varga Date: Sun, 23 Jun 2024 08:27:58 +0000 Subject: [PATCH] Bug 1903874 - Change DirectoryLock::Drop to be asynchronous; r=dom-storage-reviewers,jari For now, asynchronous Drop is only needed for replacing counting of pending clear/shutdown storage operations with evaluation of existing directory locks. In future, asynchronous Drop will also allow to do IO, for example if we decide to wait for saving of origin access time to be finished. Differential Revision: https://phabricator.services.mozilla.com/D197298 --- dom/quota/DirectoryLock.h | 2 +- dom/quota/DirectoryLockImpl.cpp | 13 +++++++++---- dom/quota/DirectoryLockImpl.h | 2 +- dom/quota/test/gtest/TestDirectoryLock.cpp | 16 ++++++++++++++-- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/dom/quota/DirectoryLock.h b/dom/quota/DirectoryLock.h index e53a9748d501..b7fbd03d4a26 100644 --- a/dom/quota/DirectoryLock.h +++ b/dom/quota/DirectoryLock.h @@ -46,7 +46,7 @@ class NS_NO_VTABLE DirectoryLock { virtual void AssertIsAcquiredExclusively() = 0; - virtual void Drop() = 0; + virtual RefPtr Drop() = 0; virtual void OnInvalidate(std::function&& aCallback) = 0; diff --git a/dom/quota/DirectoryLockImpl.cpp b/dom/quota/DirectoryLockImpl.cpp index ddfe430aac27..27c9b76d94a9 100644 --- a/dom/quota/DirectoryLockImpl.cpp +++ b/dom/quota/DirectoryLockImpl.cpp @@ -295,15 +295,20 @@ void DirectoryLockImpl::AssertIsAcquiredExclusively() { } #endif -void DirectoryLockImpl::Drop() { +RefPtr DirectoryLockImpl::Drop() { AssertIsOnOwningThread(); MOZ_ASSERT_IF(!mRegistered, mBlocking.IsEmpty()); mDropped.Flip(); - if (mRegistered) { - Unregister(); - } + return InvokeAsync(GetCurrentSerialEventTarget(), __func__, + [self = RefPtr(this)]() { + if (self->mRegistered) { + self->Unregister(); + } + + return BoolPromise::CreateAndResolve(true, __func__); + }); } void DirectoryLockImpl::OnInvalidate(std::function&& aCallback) { diff --git a/dom/quota/DirectoryLockImpl.h b/dom/quota/DirectoryLockImpl.h index dbf059665e4d..1fdb804f6a4c 100644 --- a/dom/quota/DirectoryLockImpl.h +++ b/dom/quota/DirectoryLockImpl.h @@ -202,7 +202,7 @@ class DirectoryLockImpl final : public ClientDirectoryLock, } #endif - void Drop() override; + RefPtr Drop() override; void OnInvalidate(std::function&& aCallback) override; diff --git a/dom/quota/test/gtest/TestDirectoryLock.cpp b/dom/quota/test/gtest/TestDirectoryLock.cpp index fe6d1aa8f4e5..fa03496f9bd3 100644 --- a/dom/quota/test/gtest/TestDirectoryLock.cpp +++ b/dom/quota/test/gtest/TestDirectoryLock.cpp @@ -19,7 +19,7 @@ class DOM_Quota_DirectoryLock : public QuotaManagerDependencyFixture { static void TearDownTestCase() { ASSERT_NO_FATAL_FAILURE(ShutdownFixture()); } }; -// Test that Drop unregisters directory lock synchronously. +// Test that Drop unregisters directory lock asynchronously. TEST_F(DOM_Quota_DirectoryLock, Drop_Timing) { PerformOnBackgroundThread([]() { QuotaManager* quotaManager = QuotaManager::Get(); @@ -41,7 +41,7 @@ TEST_F(DOM_Quota_DirectoryLock, Drop_Timing) { SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; }); - exclusiveDirectoryLock->Drop(); + auto exclusiveDirectoryLockDropPromise = exclusiveDirectoryLock->Drop(); exclusiveDirectoryLock = nullptr; RefPtr sharedDirectoryLock = @@ -50,6 +50,18 @@ TEST_F(DOM_Quota_DirectoryLock, Drop_Timing) { OriginScope::FromNull(), Nullable(), /* aExclusive */ false, DirectoryLockCategory::None); + ASSERT_TRUE(sharedDirectoryLock->MustWait()); + + done = false; + + exclusiveDirectoryLockDropPromise->Then( + GetCurrentSerialEventTarget(), __func__, + [&done](const BoolPromise::ResolveOrRejectValue& aValue) { + done = true; + }); + + SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; }); + ASSERT_FALSE(sharedDirectoryLock->MustWait()); sharedDirectoryLock = nullptr;