diff --git a/mozilla/netwerk/cache/src/nsCacheService.cpp b/mozilla/netwerk/cache/src/nsCacheService.cpp index c152d45b016..7aebb3b78a9 100644 --- a/mozilla/netwerk/cache/src/nsCacheService.cpp +++ b/mozilla/netwerk/cache/src/nsCacheService.cpp @@ -220,18 +220,15 @@ nsCacheProfilePrefObserver::Observe(nsISupports * subject, } else if (NS_LITERAL_STRING("profile-before-change").Equals(topic)) { // profile before change mHaveProfile = PR_FALSE; - + // XXX shutdown devices - if (NS_LITERAL_STRING("shutdown-cleanse").Equals(data)) { - // XXX we need to delete the disk cache - // printf("cache observer: shutdown-cleanse\n"); - } + nsCacheService::OnProfileShutdown(NS_LITERAL_STRING("shutdown-cleanse").Equals(data)); } else if (NS_LITERAL_STRING("profile-after-change").Equals(topic)) { // profile after change mHaveProfile = PR_TRUE; ReadPrefs(); - nsCacheService::ProfileChanged(); + nsCacheService::OnProfileChanged(); } else if (NS_LITERAL_STRING("nsPref:changed").Equals(topic)) { if (!mHaveProfile) return NS_OK; @@ -317,7 +314,7 @@ nsCacheProfilePrefObserver::ReadPrefs() if (directory) mDiskCacheParentDirectory = do_QueryInterface(directory, &rv); } - + // read memory cache device prefs rv = prefBranch->GetBoolPref(MEMORY_CACHE_ENABLE_PREF, &mMemoryCacheEnabled); if (NS_FAILED(rv)) rv2 = rv; @@ -1054,21 +1051,59 @@ nsCacheService::ProxyObjectRelease(nsISupports * object, PRThread * thread) void -nsCacheService::ProfileChanged() +nsCacheService::OnProfileShutdown(PRBool cleanse) { if (!gService) return; nsAutoLock lock(gService->mCacheServiceLock); - NS_ASSERTION(!gService->mDiskDevice, "switching cache directories not supported yet."); + if (gService->mDiskDevice) { + if (cleanse) + gService->mDiskDevice->EvictEntries(nsnull); + gService->mDiskDevice->Shutdown(); + gService->mEnableDiskDevice = PR_FALSE; + } +#if 0 + if (gService->mMemoryDevice) { + gService->mMemoryDevice->Shutdown(); + gService->mEnableMemoryDevice = PR_FALSE; + } +#endif +} + +void +nsCacheService::OnProfileChanged() +{ + if (!gService) return; + + nsresult rv = NS_OK; + nsAutoLock lock(gService->mCacheServiceLock); + gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled(); gService->mEnableMemoryDevice = gService->mObserver->MemoryCacheEnabled(); - if (gService->mDiskDevice) + if (gService->mDiskDevice) { + gService->mDiskDevice->SetCacheParentDirectory(gService->mObserver->DiskCacheParentDirectory()); gService->mDiskDevice->SetCapacity(gService->mObserver->DiskCacheCapacity()); + + // XXX initialization of mDiskDevice could be made lazily, if mEnableDiskDevice is false + rv = gService->mDiskDevice->Init(); + if (NS_FAILED(rv)) { + NS_ERROR("nsCacheService::OnProfileChanged: Re-initializing disk device failed"); + gService->mEnableDiskDevice = PR_FALSE; + // XXX delete mDiskDevice? + } + } - if (gService->mMemoryDevice) + if (gService->mMemoryDevice) { gService->mMemoryDevice->SetCapacity(gService->mObserver->MemoryCacheCapacity()); + rv = gService->mMemoryDevice->Init(); + if (NS_FAILED(rv) && (rv != NS_ERROR_ALREADY_INITIALIZED)) { + NS_ERROR("nsCacheService::OnProfileChanged: Re-initializing disk device failed"); + gService->mEnableMemoryDevice = PR_FALSE; + // XXX delete mMemoryDevice? + } + } } diff --git a/mozilla/netwerk/cache/src/nsCacheService.h b/mozilla/netwerk/cache/src/nsCacheService.h index 886fb60d4fa..43768e83bb5 100644 --- a/mozilla/netwerk/cache/src/nsCacheService.h +++ b/mozilla/netwerk/cache/src/nsCacheService.h @@ -112,7 +112,8 @@ public: /** * Methods called by nsCacheProfilePrefObserver */ - static void ProfileChanged(); + static void OnProfileShutdown(PRBool cleanse); + static void OnProfileChanged(); static void SetDiskCacheEnabled(PRBool enabled); static void SetDiskCacheCapacity(PRInt32 capacity); diff --git a/mozilla/netwerk/cache/src/nsDiskCacheBinding.cpp b/mozilla/netwerk/cache/src/nsDiskCacheBinding.cpp index df4949521d9..7dd0c2059b8 100644 --- a/mozilla/netwerk/cache/src/nsDiskCacheBinding.cpp +++ b/mozilla/netwerk/cache/src/nsDiskCacheBinding.cpp @@ -155,8 +155,7 @@ nsDiskCacheBindery::nsDiskCacheBindery() nsDiskCacheBindery::~nsDiskCacheBindery() { - if (initialized) - PL_DHashTableFinish(&table); + Reset(); } @@ -171,6 +170,15 @@ nsDiskCacheBindery::Init() return rv; } +void +nsDiskCacheBindery::Reset() +{ + if (initialized) { + PL_DHashTableFinish(&table); + initialized = PR_FALSE; + } +} + nsDiskCacheBinding * nsDiskCacheBindery::CreateBinding(nsCacheEntry * entry, diff --git a/mozilla/netwerk/cache/src/nsDiskCacheBinding.h b/mozilla/netwerk/cache/src/nsDiskCacheBinding.h index 8d4a9a5663d..035111e4e37 100644 --- a/mozilla/netwerk/cache/src/nsDiskCacheBinding.h +++ b/mozilla/netwerk/cache/src/nsDiskCacheBinding.h @@ -123,6 +123,7 @@ public: ~nsDiskCacheBindery(); nsresult Init(); + void Reset(); nsDiskCacheBinding * CreateBinding(nsCacheEntry * entry, nsDiskCacheRecord * record); diff --git a/mozilla/netwerk/cache/src/nsDiskCacheDevice.cpp b/mozilla/netwerk/cache/src/nsDiskCacheDevice.cpp index d22461b9c21..404b4dcadc1 100644 --- a/mozilla/netwerk/cache/src/nsDiskCacheDevice.cpp +++ b/mozilla/netwerk/cache/src/nsDiskCacheDevice.cpp @@ -274,6 +274,8 @@ nsresult nsDiskCacheDevice::Init() { nsresult rv; + + NS_ENSURE_TRUE(!mInitialized, NS_ERROR_FAILURE); rv = mBindery.Init(); if (NS_FAILED(rv)) return rv; @@ -327,6 +329,10 @@ nsDiskCacheDevice::Shutdown() // write out persistent information about the cache. (void) mCacheMap->Close(); + delete mCacheMap; + mCacheMap = nsnull; + + mBindery.Reset(); // no longer initialized. mInitialized = PR_FALSE; @@ -814,13 +820,17 @@ nsDiskCacheDevice::SetCacheParentDirectory(nsILocalFile * parentDir) { nsresult rv; PRBool exists; - NS_ASSERTION(mCacheDirectory == nsnull, "switching cache directories not supportted."); - + + if (mInitialized) { + NS_ASSERTION(PR_FALSE, "Cannot switch cache directory when initialized"); + return; + } + if (!parentDir) { mCacheDirectory = nsnull; return; } - + // ensure parent directory exists rv = parentDir->Exists(&exists); if (NS_SUCCEEDED(rv) && !exists) diff --git a/mozilla/netwerk/cache/src/nsMemoryCacheDevice.cpp b/mozilla/netwerk/cache/src/nsMemoryCacheDevice.cpp index ecd5cf9c955..e9cd9a08e04 100644 --- a/mozilla/netwerk/cache/src/nsMemoryCacheDevice.cpp +++ b/mozilla/netwerk/cache/src/nsMemoryCacheDevice.cpp @@ -41,7 +41,8 @@ const char *gMemoryDeviceID = "memory"; nsMemoryCacheDevice::nsMemoryCacheDevice() - : mEvictionThreshold(40 * 1024), + : mInitialized(PR_FALSE), + mEvictionThreshold(40 * 1024), mHardLimit(4 * 1024 * 1024), // set default memory limit, in case prefs aren't available mTotalSize(0), mInactiveSize(0), @@ -62,21 +63,25 @@ nsMemoryCacheDevice::~nsMemoryCacheDevice() nsresult nsMemoryCacheDevice::Init() { - nsresult rv; + if (mInitialized) return NS_ERROR_ALREADY_INITIALIZED; - rv = mMemCacheEntries.Init(); + nsresult rv = mMemCacheEntries.Init(); // set some default memory limits, in case prefs aren't available mSoftLimit = mHardLimit * 0.9; // XXX Register as a memory pressure observer - + mInitialized = NS_SUCCEEDED(rv); return rv; } + nsresult nsMemoryCacheDevice::Shutdown() { + NS_ASSERTION(mInitialized, "### attempting to shutdown while not initialized.\n"); + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + mMemCacheEntries.Shutdown(); // evict all entries @@ -107,9 +112,11 @@ nsMemoryCacheDevice::Shutdown() NS_ASSERTION(mInactiveSize == 0, "### mem cache leaking entries?\n"); NS_ASSERTION(mEntryCount == 0, "### mem cache leaking entries?\n"); + mInitialized = PR_FALSE; return NS_OK; } + const char * nsMemoryCacheDevice::GetDeviceID() { diff --git a/mozilla/netwerk/cache/src/nsMemoryCacheDevice.h b/mozilla/netwerk/cache/src/nsMemoryCacheDevice.h index d959af159e5..d6f37056882 100644 --- a/mozilla/netwerk/cache/src/nsMemoryCacheDevice.h +++ b/mozilla/netwerk/cache/src/nsMemoryCacheDevice.h @@ -77,6 +77,7 @@ private: */ nsCacheEntryHashTable mMemCacheEntries; + PRBool mInitialized; enum { mostLikelyToEvict = 0, leastLikelyToEvict = 1 }; // constants to differentiate eviction lists PRCList mEvictionList[2];