commit 8cc9073e81a6e469aa088fd37327bcccc367cb44
parent 41e4c77b77e3d31c416f58cbea290e5d011a6963
Author: Randell Jesup <rjesup@mozilla.com>
Date: Tue, 7 Oct 2025 17:55:51 +0000
Bug 1975024: Cleanup Cache code and locks in prep for Compression Dictionaries #necko-reviewers r=necko-reviewers,kershaw
Differential Revision: https://phabricator.services.mozilla.com/D255678
Diffstat:
3 files changed, 69 insertions(+), 48 deletions(-)
diff --git a/netwerk/cache2/CacheEntry.cpp b/netwerk/cache2/CacheEntry.cpp
@@ -266,6 +266,12 @@ nsresult CacheEntry::HashingKey(const nsACString& aStorageID,
return HashingKey(aStorageID, aEnhanceID, spec, aResult);
}
+// The hash key (which is also the filename) is:
+// A[~B]:C
+// Where A is the storage ID ([O<oa>,][a,][p,]), B is the optional 'id',
+// and C is the URI 'oa' are the OriginAttributes in suffix form
+// (i.e. |^key=value&key2=value2|)
+
// static
nsresult CacheEntry::HashingKey(const nsACString& aStorageID,
const nsACString& aEnhanceID,
diff --git a/netwerk/cache2/CacheStorageService.cpp b/netwerk/cache2/CacheStorageService.cpp
@@ -39,6 +39,10 @@
namespace mozilla::net {
+// static
+GlobalEntryTables* CacheStorageService::sGlobalEntryTables = nullptr;
+mozilla::Mutex CacheStorageService::sLock{"CacheStorageService.sLock"};
+
namespace {
void AppendMemoryStorageTag(nsAutoCString& key) {
@@ -50,21 +54,6 @@ void AppendMemoryStorageTag(nsAutoCString& key) {
} // namespace
-// Not defining as static or class member of CacheStorageService since
-// it would otherwise need to include CacheEntry.h and that then would
-// need to be exported to make nsNetModule.cpp compilable.
-using GlobalEntryTables = nsClassHashtable<nsCStringHashKey, CacheEntryTable>;
-
-/**
- * Keeps tables of entries. There is one entries table for each distinct load
- * context type. The distinction is based on following load context info
- * states: <isPrivate|isAnon|inIsolatedMozBrowser> which builds a mapping
- * key.
- *
- * Thread-safe to access, protected by the service mutex.
- */
-static GlobalEntryTables* sGlobalEntryTables;
-
CacheMemoryConsumer::CacheMemoryConsumer(uint32_t aFlags) {
StoreFlags(aFlags);
}
@@ -133,7 +122,7 @@ CacheStorageService::~CacheStorageService() {
}
void CacheStorageService::Shutdown() {
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
if (mShutdown) return;
@@ -161,7 +150,7 @@ void CacheStorageService::ShutdownBackground() {
MOZ_ASSERT(IsOnManagementThread());
{
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
// Cancel purge timer to avoid leaking.
if (mPurgeTimer) {
@@ -180,7 +169,7 @@ void CacheStorageService::ShutdownBackground() {
// Internal management methods
-namespace {
+namespace CacheStorageServiceInternal {
// WalkCacheRunnable
// Base class for particular storage entries visiting
@@ -237,13 +226,14 @@ class WalkMemoryCacheRunnable : public WalkCacheRunnable {
LOG(("WalkMemoryCacheRunnable::Run - collecting [this=%p]", this));
// First, walk, count and grab all entries from the storage
- mozilla::MutexAutoLock lock(CacheStorageService::Self()->Lock());
+ mozilla::MutexAutoLock lock(CacheStorageService::sLock);
if (!CacheStorageService::IsRunning()) return NS_ERROR_NOT_INITIALIZED;
// Count the entries to allocate the array memory all at once.
size_t numEntries = 0;
- for (const auto& entries : sGlobalEntryTables->Values()) {
+ for (const auto& entries :
+ CacheStorageService::sGlobalEntryTables->Values()) {
if (entries->Type() != CacheEntryTable::MEMORY_ONLY) {
continue;
}
@@ -252,7 +242,8 @@ class WalkMemoryCacheRunnable : public WalkCacheRunnable {
mEntryArray.SetCapacity(numEntries);
// Collect the entries.
- for (const auto& entries : sGlobalEntryTables->Values()) {
+ for (const auto& entries :
+ CacheStorageService::sGlobalEntryTables->Values()) {
if (entries->Type() != CacheEntryTable::MEMORY_ONLY) {
continue;
}
@@ -528,10 +519,10 @@ class WalkDiskCacheRunnable : public WalkCacheRunnable {
uint32_t mCount;
};
-} // namespace
+} // namespace CacheStorageServiceInternal
void CacheStorageService::DropPrivateBrowsingEntries() {
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
if (mShutdown) return;
@@ -673,7 +664,7 @@ NS_IMETHODIMP CacheStorageService::Clear() {
// when all the context have been removed from disk.
CacheIndex::OnAsyncEviction(true);
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
{
mozilla::MutexAutoLock forcedValidEntriesLock(mForcedValidEntriesLock);
@@ -756,9 +747,8 @@ static bool RemoveExactEntry(CacheEntryTable* aEntries, nsACString const& aKey,
NS_IMETHODIMP CacheStorageService::ClearBaseDomain(
const nsAString& aBaseDomain) {
+ mozilla::MutexAutoLock lock(sLock);
if (sGlobalEntryTables) {
- mozilla::MutexAutoLock lock(mLock);
-
if (mShutdown) return NS_ERROR_NOT_AVAILABLE;
nsCString cBaseDomain = NS_ConvertUTF16toUTF8(aBaseDomain);
@@ -845,7 +835,7 @@ nsresult CacheStorageService::ClearOriginInternal(
return NS_ERROR_FAILURE;
}
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
if (sGlobalEntryTables) {
for (const auto& globalEntry : *sGlobalEntryTables) {
@@ -978,8 +968,9 @@ NS_IMETHODIMP CacheStorageService::AsyncVisitAllStorages(
NS_ENSURE_FALSE(mShutdown, NS_ERROR_NOT_INITIALIZED);
// Walking the disk cache also walks the memory cache.
- RefPtr<WalkDiskCacheRunnable> event =
- new WalkDiskCacheRunnable(nullptr, aVisitEntries, aVisitor);
+ RefPtr<CacheStorageServiceInternal::WalkDiskCacheRunnable> event =
+ new CacheStorageServiceInternal::WalkDiskCacheRunnable(
+ nullptr, aVisitEntries, aVisitor);
return event->Walk();
}
@@ -1041,7 +1032,7 @@ bool CacheStorageService::RemoveEntry(CacheEntry* aEntry,
return false;
}
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
if (mShutdown) {
LOG((" after shutdown"));
@@ -1089,7 +1080,7 @@ void CacheStorageService::RecordMemoryOnlyEntry(CacheEntry* aEntry,
// not is always recorded in the storage master hash table, the one identified
// by CacheEntry.StorageID().
- mLock.AssertCurrentThreadOwns();
+ sLock.AssertCurrentThreadOwns();
if (mShutdown) {
LOG((" after shutdown"));
@@ -1291,7 +1282,7 @@ bool CacheStorageService::MemoryPool::OnMemoryConsumptionChange(
void CacheStorageService::SchedulePurgeOverMemoryLimit() {
LOG(("CacheStorageService::SchedulePurgeOverMemoryLimit"));
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
if (mShutdown) {
LOG((" past shutdown"));
@@ -1318,7 +1309,7 @@ NS_IMETHODIMP
CacheStorageService::Notify(nsITimer* aTimer) {
LOG(("CacheStorageService::Notify"));
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
if (aTimer == mPurgeTimer) {
#ifdef MOZ_TSAN
@@ -1592,7 +1583,7 @@ nsresult CacheStorageService::AddStorageEntry(
RefPtr<CacheEntryHandle> handle;
{
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
NS_ENSURE_FALSE(mShutdown, NS_ERROR_NOT_INITIALIZED);
@@ -1688,7 +1679,7 @@ nsresult CacheStorageService::CheckStorageEntry(CacheStorage const* aStorage,
aURI.BeginReading(), aIdExtension.BeginReading(), contextKey.get()));
{
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
NS_ENSURE_FALSE(mShutdown, NS_ERROR_NOT_INITIALIZED);
@@ -1849,7 +1840,7 @@ nsresult CacheStorageService::DoomStorageEntry(
RefPtr<CacheEntry> entry;
{
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
NS_ENSURE_FALSE(mShutdown, NS_ERROR_NOT_INITIALIZED);
@@ -1936,7 +1927,7 @@ nsresult CacheStorageService::DoomStorageEntries(
nsAutoCString contextKey;
CacheFileUtils::AppendKeyPrefix(aStorage->LoadInfo(), contextKey);
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
return DoomStorageEntries(contextKey, aStorage->LoadInfo(),
aStorage->WriteToDisk(), aStorage->Pinning(),
@@ -1949,7 +1940,7 @@ nsresult CacheStorageService::DoomStorageEntries(
LOG(("CacheStorageService::DoomStorageEntries [context=%s]",
aContextKey.BeginReading()));
- mLock.AssertCurrentThreadOwns();
+ sLock.AssertCurrentThreadOwns();
NS_ENSURE_TRUE(!mShutdown, NS_ERROR_NOT_INITIALIZED);
@@ -2054,13 +2045,15 @@ nsresult CacheStorageService::WalkStorageEntries(
NS_ENSURE_ARG(aStorage);
if (aStorage->WriteToDisk()) {
- RefPtr<WalkDiskCacheRunnable> event = new WalkDiskCacheRunnable(
- aStorage->LoadInfo(), aVisitEntries, aVisitor);
+ RefPtr<CacheStorageServiceInternal::WalkDiskCacheRunnable> event =
+ new CacheStorageServiceInternal::WalkDiskCacheRunnable(
+ aStorage->LoadInfo(), aVisitEntries, aVisitor);
return event->Walk();
}
- RefPtr<WalkMemoryCacheRunnable> event = new WalkMemoryCacheRunnable(
- aStorage->LoadInfo(), aVisitEntries, aVisitor);
+ RefPtr<CacheStorageServiceInternal::WalkMemoryCacheRunnable> event =
+ new CacheStorageServiceInternal::WalkMemoryCacheRunnable(
+ aStorage->LoadInfo(), aVisitEntries, aVisitor);
return event->Walk();
}
@@ -2073,7 +2066,7 @@ void CacheStorageService::CacheFileDoomed(nsILoadContextInfo* aLoadContextInfo,
nsAutoCString entryKey;
CacheEntry::HashingKey(""_ns, aIdExtension, aURISpec, entryKey);
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
if (mShutdown) {
return;
@@ -2110,7 +2103,7 @@ bool CacheStorageService::GetCacheEntryInfo(
RefPtr<CacheEntry> entry;
{
- mozilla::MutexAutoLock lock(mLock);
+ mozilla::MutexAutoLock lock(sLock);
if (mShutdown) {
return false;
@@ -2269,7 +2262,7 @@ void CacheStorageService::TelemetryRecordEntryRemoval(CacheEntry* entry) {
size_t CacheStorageService::SizeOfExcludingThis(
mozilla::MallocSizeOf mallocSizeOf) const {
- CacheStorageService::Self()->Lock().AssertCurrentThreadOwns();
+ sLock.AssertCurrentThreadOwns();
size_t n = 0;
// The elemets are referenced by sGlobalEntryTables and are reported from
@@ -2292,7 +2285,7 @@ size_t CacheStorageService::SizeOfIncludingThis(
NS_IMETHODIMP
CacheStorageService::CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize) {
- MutexAutoLock lock(mLock);
+ MutexAutoLock lock(sLock);
MOZ_COLLECT_REPORT("explicit/network/cache2/io", KIND_HEAP, UNITS_BYTES,
CacheFileIOManager::SizeOfIncludingThis(MallocSizeOf),
"Memory used by the cache IO manager.");
diff --git a/netwerk/cache2/CacheStorageService.h b/netwerk/cache2/CacheStorageService.h
@@ -41,6 +41,7 @@ class CacheStorageService;
class CacheStorage;
class CacheEntry;
class CacheEntryHandle;
+class CacheEntryTable;
class CacheMemoryConsumer {
private:
@@ -73,11 +74,22 @@ class CacheMemoryConsumer {
void DoMemoryReport(uint32_t aCurrentSize);
};
+using GlobalEntryTables = nsClassHashtable<nsCStringHashKey, CacheEntryTable>;
+class WalkMemoryCacheRunnable;
+
+namespace CacheStorageServiceInternal {
+class WalkMemoryCacheRunnable;
+class WalkDiskCacheRunnable;
+} // namespace CacheStorageServiceInternal
+
class CacheStorageService final : public nsICacheStorageService,
public nsIMemoryReporter,
public nsITimerCallback,
public nsICacheTesting,
public nsINamed {
+ friend class CacheStorageServiceInternal::WalkMemoryCacheRunnable;
+ friend class CacheStorageServiceInternal::WalkDiskCacheRunnable;
+
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSICACHESTORAGESERVICE
@@ -99,7 +111,7 @@ class CacheStorageService final : public nsICacheStorageService,
static bool IsRunning() { return sSelf && !sSelf->mShutdown; }
static bool IsOnManagementThread();
already_AddRefed<nsIEventTarget> Thread() const;
- mozilla::Mutex& Lock() { return mLock; }
+ mozilla::Mutex& Lock() { return sLock; }
// Tracks entries that may be forced valid in a pruned hashtable.
struct ForcedValidData {
@@ -145,6 +157,16 @@ class CacheStorageService final : public nsICacheStorageService,
virtual ~CacheStorageService();
void ShutdownBackground();
+ /**
+ * Keeps tables of entries. There is one entries table for each distinct load
+ * context type. The distinction is based on following load context info
+ * states: <isPrivate|isAnon|inIsolatedMozBrowser> which builds a mapping
+ * key.
+ *
+ * Thread-safe to access, protected by the service mutex.
+ */
+ static GlobalEntryTables* sGlobalEntryTables MOZ_GUARDED_BY(sLock);
+
private:
// The following methods may only be called on the management
// thread.
@@ -322,7 +344,7 @@ class CacheStorageService final : public nsICacheStorageService,
static CacheStorageService* sSelf;
- mozilla::Mutex mLock MOZ_UNANNOTATED{"CacheStorageService.mLock"};
+ static mozilla::Mutex sLock;
mozilla::Mutex mForcedValidEntriesLock{
"CacheStorageService.mForcedValidEntriesLock"};