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;