[not part of build] Using nsIPref::AddObserver() instead of krufty old callbacks. Using directory service to obtain profile directory and using a "profile-do-change" observer to regenerate the cache directory.

This commit is contained in:
beard%netscape.com 2001-03-14 03:35:09 +00:00
Родитель 752a3f6947
Коммит b9c6dbc105
2 изменённых файлов: 159 добавлений и 80 удалений

235
netwerk/cache/src/nsDiskCacheDevice.cpp поставляемый
Просмотреть файл

@ -27,13 +27,16 @@
#include "nsICacheService.h"
#include "nsIFileTransportService.h"
#include "nsDirectoryServiceDefs.h"
#include "nsITransport.h"
#include "nsICacheVisitor.h"
#include "nsXPIDLString.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsISupportsArray.h"
#include "nsITransport.h"
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIObserverService.h"
#include "nsIPref.h"
static const char DISK_CACHE_DEVICE_ID[] = { "disk" };
@ -42,43 +45,67 @@ static const char DISK_CACHE_DEVICE_ID[] = { "disk" };
// Using nsIPref will be subsumed with nsIDirectoryService when a selector
// for the cache directory has been defined.
#include "nsIPref.h"
#define CACHE_DIR_PREF "browser.newcache.directory"
#define CACHE_DISK_CAPACITY_PREF "browser.cache.disk_cache_size"
static const char CACHE_DIR_PREF[] = { "browser.newcache.directory" };
static const char CACHE_DISK_CAPACITY[] = { "browser.cache.disk_cache_size" };
class nsDiskCacheObserver : public nsIObserver {
nsDiskCacheDevice* mDevice;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
static int PR_CALLBACK cacheDirectoryChanged(const char *pref, void *closure)
nsDiskCacheObserver(nsDiskCacheDevice * device)
: mDevice(device)
{
}
virtual ~nsDiskCacheObserver() {}
};
NS_IMPL_ISUPPORTS1(nsDiskCacheObserver, nsIObserver);
NS_IMETHODIMP nsDiskCacheObserver::Observe(nsISupports *aSubject, const PRUnichar *aTopic, const PRUnichar *someData)
{
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
nsresult rv;
nsCOMPtr<nsILocalFile> cacheDirectory;
rv = prefs->GetFileXPref(CACHE_DIR_PREF, getter_AddRefs( cacheDirectory ));
if (NS_FAILED(rv))
return rv;
nsDiskCacheDevice* device = NS_STATIC_CAST(nsDiskCacheDevice*, closure);
device->setCacheDirectory(cacheDirectory);
return NS_OK;
}
static int PR_CALLBACK cacheCapacityChanged(const char *pref, void *closure)
{
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
PRInt32 cacheCapacity;
rv = prefs->GetIntPref(CACHE_DISK_CAPACITY, &cacheCapacity);
if (NS_FAILED(rv))
return rv;
nsDiskCacheDevice* device = NS_STATIC_CAST(nsDiskCacheDevice*, closure);
device->setCacheCapacity(cacheCapacity);
// did a preference change?
nsLiteralString aTopicString(aTopic);
if (aTopicString.Equals(NS_LITERAL_STRING("nsPref:changed"))) {
// when bug #71879 gets fixed, this QueryInterface will succeed!
nsCOMPtr<nsIPref> prefs = do_QueryInterface(aSubject, &rv);
if (!prefs) {
prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
}
// which preference changed?
nsLiteralString prefName(someData);
if (prefName.Equals(NS_LITERAL_STRING(CACHE_DIR_PREF))) {
nsCOMPtr<nsILocalFile> cacheDirectory;
rv = prefs->GetFileXPref(CACHE_DIR_PREF, getter_AddRefs(cacheDirectory));
if (NS_SUCCEEDED(rv))
mDevice->setCacheDirectory(cacheDirectory);
} else
if (prefName.Equals(NS_LITERAL_STRING(CACHE_DISK_CAPACITY_PREF))) {
PRInt32 cacheCapacity;
rv = prefs->GetIntPref(CACHE_DISK_CAPACITY_PREF, &cacheCapacity);
if (NS_SUCCEEDED(rv))
mDevice->setCacheCapacity(cacheCapacity);
}
} else if (aTopicString.Equals(NS_LITERAL_STRING("profile-do-change"))) {
// XXX need to regenerate the cache directory. hopefully the
// cache service has already been informed of this change.
nsCOMPtr<nsIFile> profileDir;
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(profileDir));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsILocalFile> cacheDirectory = do_QueryInterface(profileDir);
if (cacheDirectory) {
cacheDirectory->Append("NewCache");
mDevice->setCacheDirectory(cacheDirectory);
}
}
}
return NS_OK;
}
@ -93,86 +120,121 @@ static nsresult ensureCacheDirectory(nsIFile * cacheDirectory)
return rv;
}
static nsresult installPrefListeners(nsDiskCacheDevice* device)
static nsresult installObservers(nsDiskCacheDevice* device)
{
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv);
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
rv = prefs->RegisterCallback(CACHE_DISK_CAPACITY, cacheCapacityChanged, device);
nsCOMPtr<nsIObserver> observer = new nsDiskCacheObserver(device);
if (!observer) return NS_ERROR_OUT_OF_MEMORY;
device->setPrefsObserver(observer);
rv = prefs->AddObserver(CACHE_DISK_CAPACITY_PREF, observer);
if (NS_FAILED(rv))
return rv;
PRInt32 cacheCapacity;
rv = prefs->GetIntPref(CACHE_DISK_CAPACITY, &cacheCapacity);
rv = prefs->GetIntPref(CACHE_DISK_CAPACITY_PREF, &cacheCapacity);
if (NS_FAILED(rv)) {
#if DEBUG
const PRInt32 kTenMegabytes = 10 * 1024 * 1024;
rv = prefs->SetIntPref(CACHE_DISK_CAPACITY, kTenMegabytes);
rv = prefs->SetIntPref(CACHE_DISK_CAPACITY_PREF, kTenMegabytes);
#else
return rv;
#endif
} else {
device->setCacheCapacity(cacheCapacity);
// XXX note the units of the pref seems to be in kilobytes.
device->setCacheCapacity(cacheCapacity * 1024);
}
rv = prefs->RegisterCallback(CACHE_DIR_PREF, cacheDirectoryChanged, device);
rv = prefs->AddObserver(CACHE_DIR_PREF, observer);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsILocalFile> cacheDirectory;
rv = prefs->GetFileXPref(CACHE_DIR_PREF, getter_AddRefs(cacheDirectory));
if (NS_FAILED(rv)) {
// XXX no preference has been defined, use the directory service. instead.
nsCOMPtr<nsIFile> profileDir;
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(profileDir));
if (NS_SUCCEEDED(rv)) {
// XXX this path will probably only succeed when running under Mozilla.
// store the new disk cache files in a directory called NewCache
// in the interim.
cacheDirectory = do_QueryInterface(profileDir, &rv);
if (NS_FAILED(rv))
return rv;
rv = cacheDirectory->Append("NewCache");
if (NS_FAILED(rv))
return rv;
// XXX since we didn't find a preference, we'll assume that the cache directory
// can only change when profiles change, so remove the prefs listener and install
// a profile listener.
prefs->RemoveObserver(CACHE_DIR_PREF, observer);
nsCOMPtr<nsIObserverService> observerService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
if (observerService)
observerService->AddObserver(observer, NS_LITERAL_STRING("profile-do-change").get());
} else {
#if DEBUG
// XXX use current process directory during development only.
nsCOMPtr<nsIFile> currentProcessDir;
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
getter_AddRefs(currentProcessDir));
if (NS_FAILED(rv))
return rv;
// XXX use current process directory during development only.
nsCOMPtr<nsIFile> currentProcessDir;
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
getter_AddRefs(currentProcessDir));
if (NS_FAILED(rv))
return rv;
cacheDirectory = do_QueryInterface(currentProcessDir, &rv);
if (NS_FAILED(rv))
return rv;
rv = cacheDirectory->Append("Cache");
if (NS_FAILED(rv))
return rv;
cacheDirectory = do_QueryInterface(currentProcessDir, &rv);
if (NS_FAILED(rv))
return rv;
rv = ensureCacheDirectory(cacheDirectory);
if (NS_FAILED(rv))
return rv;
rv = prefs->SetFileXPref(CACHE_DIR_PREF, cacheDirectory);
if (NS_FAILED(rv))
return rv;
rv = cacheDirectory->Append("Cache");
if (NS_FAILED(rv))
return rv;
#else
return rv;
#endif
} else {
// always make sure the directory exists, the user may blow it away.
rv = ensureCacheDirectory(cacheDirectory);
if (NS_FAILED(rv))
return rv;
// cause the preference to be set up initially.
device->setCacheDirectory(cacheDirectory);
#endif
}
}
// always make sure the directory exists, the user may blow it away.
rv = ensureCacheDirectory(cacheDirectory);
if (NS_FAILED(rv))
return rv;
// cause the preference to be set up initially.
device->setCacheDirectory(cacheDirectory);
return NS_OK;
}
static nsresult removePrefListeners(nsDiskCacheDevice* device)
static nsresult removeObservers(nsDiskCacheDevice* device)
{
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv);
if ( NS_FAILED (rv ) )
return rv;
nsresult rv;
rv = prefs->UnregisterCallback(CACHE_DIR_PREF, cacheDirectoryChanged, device);
if ( NS_FAILED( rv ) )
return rv;
nsCOMPtr<nsIObserver> observer;
device->getPrefsObserver(getter_AddRefs(observer));
device->setPrefsObserver(nsnull);
NS_ASSERTION(observer, "removePrefListeners");
if (observer) {
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
if (prefs) {
prefs->RemoveObserver(CACHE_DISK_CAPACITY_PREF, observer);
prefs->RemoveObserver(CACHE_DIR_PREF, observer);
}
nsCOMPtr<nsIObserverService> observerService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
if (observerService)
observerService->RemoveObserver(observer, NS_LITERAL_STRING("profile-do-change").get());
}
return NS_OK;
}
@ -555,25 +617,28 @@ nsDiskCacheDevice::nsDiskCacheDevice()
nsDiskCacheDevice::~nsDiskCacheDevice()
{
removePrefListeners(this);
removeObservers(this);
// XXX implement poor man's eviction strategy right here,
// keep deleting cache entries from oldest to newest, until
// cache usage is brought below limits.
evictDiskCacheEntries();
// XXX release the reference to the cached file transport service.
gFileTransportService = nsnull;
}
nsresult
nsDiskCacheDevice::Init()
{
nsresult rv = installPrefListeners(this);
nsresult rv = installObservers(this);
if (NS_FAILED(rv)) return rv;
rv = mBoundEntries.Init();
if (NS_FAILED(rv)) return rv;
// XXX cache the file transport service to avoid repeated round trips
// through the service manager.
gFileTransportService = do_GetService("@mozilla.org/network/file-transport-service;1", &rv);
if (NS_FAILED(rv)) return rv;
@ -794,6 +859,16 @@ nsDiskCacheDevice::Visit(nsICacheVisitor * visitor)
return NS_OK;
}
void nsDiskCacheDevice::setPrefsObserver(nsIObserver* observer)
{
mPrefsObserver = observer;
}
void nsDiskCacheDevice::getPrefsObserver(nsIObserver** result)
{
NS_IF_ADDREF(*result = mPrefsObserver);
}
void nsDiskCacheDevice::setCacheDirectory(nsILocalFile* cacheDirectory)
{
mCacheDirectory = cacheDirectory;

4
netwerk/cache/src/nsDiskCacheDevice.h поставляемый
Просмотреть файл

@ -27,6 +27,7 @@
#include "nsCacheDevice.h"
#include "nsILocalFile.h"
#include "nsCacheEntry.h"
#include "nsIObserver.h"
class DiskCacheEntry;
class nsISupportsArray;
@ -58,6 +59,8 @@ public:
virtual nsresult Visit(nsICacheVisitor * visitor);
/* private: */
void setPrefsObserver(nsIObserver* observer);
void getPrefsObserver(nsIObserver ** result);
void setCacheDirectory(nsILocalFile* directory);
void setCacheCapacity(PRUint32 capacity);
PRUint32 getCacheCapacity();
@ -81,6 +84,7 @@ private:
nsresult evictDiskCacheEntries();
private:
nsCOMPtr<nsIObserver> mPrefsObserver;
nsCOMPtr<nsILocalFile> mCacheDirectory;
nsCacheEntryHashTable mBoundEntries;
PRUint32 mCacheCapacity;