gecko-dev/dom/quota/OpenClientDirectoryInfo.cpp
Jan Varga c2d2585dd3 Bug 1962129 - QM: Block client access until origin access time update completes; r=dom-storage-reviewers,hsingh,asuth
Ensures that quota clients cannot access their client directories until the
origin access time update (triggered on first access) has completed. This
establishes a clear boundary between metadata updates and client operations,
and prevents inconsistencies if the application crashes.

This is a necessary prerequisite for reliably using the `accessed` flag in the
metadata file to determine whether cached usage is valid or if a full scan is
required during storage initialization.

The patch introduces blocking behavior for all handles registered after the
first one, ensuring that quota clients wait for the access time update to
complete before proceeding.

Differential Revision: https://phabricator.services.mozilla.com/D246713
2025-06-10 13:01:12 +00:00

85 lines
2.5 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/quota/OpenClientDirectoryInfo.h"
#include "mozilla/dom/quota/AssertionsImpl.h"
#include "mozilla/dom/quota/UniversalDirectoryLock.h"
namespace mozilla::dom::quota {
OpenClientDirectoryInfo::OpenClientDirectoryInfo() {
MOZ_COUNT_CTOR(mozilla::dom::quota::OpenClientDirectoryInfo);
}
OpenClientDirectoryInfo::~OpenClientDirectoryInfo() {
MOZ_COUNT_DTOR(mozilla::dom::quota::OpenClientDirectoryInfo);
}
void OpenClientDirectoryInfo::AssertIsOnOwningThread() const {
NS_ASSERT_OWNINGTHREAD(OpenClientDirectoryInfo);
}
void OpenClientDirectoryInfo::SetFirstAccessPromise(
RefPtr<BoolPromise> aFirstAccessPromise) {
AssertIsOnOwningThread();
MOZ_ASSERT(aFirstAccessPromise);
MOZ_ASSERT(!mFirstAccessPromise);
mFirstAccessPromise = std::move(aFirstAccessPromise);
}
RefPtr<BoolPromise> OpenClientDirectoryInfo::AcquireFirstAccessPromise() const {
AssertIsOnOwningThread();
MOZ_ASSERT(mFirstAccessPromise);
return mFirstAccessPromise;
}
void OpenClientDirectoryInfo::SetLastAccessDirectoryLock(
RefPtr<UniversalDirectoryLock> aLastAccessDirectoryLock) {
AssertIsOnOwningThread();
MOZ_ASSERT(aLastAccessDirectoryLock);
MOZ_ASSERT(!mLastAccessDirectoryLock);
mLastAccessDirectoryLock = std::move(aLastAccessDirectoryLock);
}
bool OpenClientDirectoryInfo::HasLastAccessDirectoryLock() const {
AssertIsOnOwningThread();
return mLastAccessDirectoryLock;
}
RefPtr<UniversalDirectoryLock>
OpenClientDirectoryInfo::ForgetLastAccessDirectoryLock() {
AssertIsOnOwningThread();
MOZ_ASSERT(mLastAccessDirectoryLock);
return std::move(mLastAccessDirectoryLock);
}
uint64_t OpenClientDirectoryInfo::ClientDirectoryLockHandleCount() const {
AssertIsOnOwningThread();
return mClientDirectoryLockHandleCount;
}
void OpenClientDirectoryInfo::IncreaseClientDirectoryLockHandleCount() {
AssertIsOnOwningThread();
AssertNoOverflow(mClientDirectoryLockHandleCount, 1);
mClientDirectoryLockHandleCount++;
}
void OpenClientDirectoryInfo::DecreaseClientDirectoryLockHandleCount() {
AssertIsOnOwningThread();
AssertNoUnderflow(mClientDirectoryLockHandleCount, 1);
mClientDirectoryLockHandleCount--;
}
} // namespace mozilla::dom::quota