зеркало из https://github.com/mozilla/pjs.git
fixes bug 321833 "Clearing the cache prevents disk cache from working" r=mconnor, alfredkayser
This commit is contained in:
Родитель
c66402ebc4
Коммит
698fec901b
|
@ -98,50 +98,9 @@ Sanitizer.prototype = {
|
|||
const ci = Components.interfaces;
|
||||
var cacheService = cc["@mozilla.org/network/cache-service;1"]
|
||||
.getService(ci.nsICacheService);
|
||||
|
||||
// Here we play dirty, trying to brutally wipe out all the cache files
|
||||
// even if the disk cache device has gone away (if it is still with us,
|
||||
// our removal attempt will fail because the directory is locked,
|
||||
// and we fall back to the "nice" way below)
|
||||
|
||||
var cacheDir;
|
||||
// Look at nsCacheProfilePrefObserver::ReadPrefs()
|
||||
// and nsDiskCacheDevice::SetCacheParentDirectory()
|
||||
// for details on how we guess the cache directory
|
||||
try {
|
||||
cacheDir = cc["@mozilla.org/preferences-service;1"]
|
||||
.getService(ci.nsIPrefBranch)
|
||||
.getComplexValue("browser.cache.disk.parent_directory",
|
||||
ci.nsILocalFile);
|
||||
} catch(er) {
|
||||
const dirServ = cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(ci.nsIProperties);
|
||||
try {
|
||||
cacheDir = dirServ.get("cachePDir",ci.nsILocalFile);
|
||||
} catch(er) {
|
||||
cacheDir = dirServ.get("ProfLD",ci.nsILocalFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheDir) {
|
||||
// Here we try to prevent the "phantom Cache.Trash" issue
|
||||
// reported in bug #296256
|
||||
cacheDir.append("Cache.Trash");
|
||||
try {
|
||||
cacheDir.remove(true);
|
||||
} catch(er) {}
|
||||
cacheDir = cacheDir.parent;
|
||||
cacheDir.append("Cache");
|
||||
try {
|
||||
cacheDir.remove(true);
|
||||
} catch(er) {}
|
||||
}
|
||||
|
||||
try {
|
||||
// The "nice" way
|
||||
cacheService.evictEntries(ci.nsICache.STORE_ANYWHERE);
|
||||
} catch(er) {}
|
||||
|
||||
},
|
||||
|
||||
get canClear()
|
||||
|
|
|
@ -356,7 +356,7 @@ nsCacheProfilePrefObserver::ReadPrefs(nsIPrefBranch* branch)
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool exists;
|
||||
if (NS_SUCCEEDED(profDir->Exists(&exists)) && exists)
|
||||
DeleteDir(profDir, PR_FALSE);
|
||||
DeleteDir(profDir, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ PR_STATIC_CALLBACK(void) DeleteDirThreadFunc(void *arg)
|
|||
NS_RELEASE(dir);
|
||||
}
|
||||
|
||||
nsresult DeleteDir(nsIFile *dirIn, PRBool moveToTrash)
|
||||
nsresult DeleteDir(nsIFile *dirIn, PRBool moveToTrash, PRBool sync)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> trash, dir;
|
||||
|
@ -92,16 +92,23 @@ nsresult DeleteDir(nsIFile *dirIn, PRBool moveToTrash)
|
|||
nsIFile *trashRef = nsnull;
|
||||
trash.swap(trashRef);
|
||||
|
||||
// now, invoke the worker thread
|
||||
PRThread *thread = PR_CreateThread(PR_USER_THREAD,
|
||||
DeleteDirThreadFunc,
|
||||
trashRef,
|
||||
PR_PRIORITY_LOW,
|
||||
PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD,
|
||||
0);
|
||||
if (!thread)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
if (sync)
|
||||
{
|
||||
DeleteDirThreadFunc(trashRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
// now, invoke the worker thread
|
||||
PRThread *thread = PR_CreateThread(PR_USER_THREAD,
|
||||
DeleteDirThreadFunc,
|
||||
trashRef,
|
||||
PR_PRIORITY_LOW,
|
||||
PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD,
|
||||
0);
|
||||
if (!thread)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -56,8 +56,11 @@ class nsIFile;
|
|||
*
|
||||
* If the moveToTrash parameter is false, then the given directory is deleted
|
||||
* directly.
|
||||
*
|
||||
* If the sync flag is true, then the delete operation runs to completion
|
||||
* before this function returns. Otherwise, deletion occurs asynchronously.
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) DeleteDir(nsIFile *dir, PRBool moveToTrash);
|
||||
NS_HIDDEN_(nsresult) DeleteDir(nsIFile *dir, PRBool moveToTrash, PRBool sync);
|
||||
|
||||
/**
|
||||
* This routine returns the trash directory corresponding to the given
|
||||
|
|
|
@ -385,14 +385,29 @@ error_exit:
|
|||
nsresult
|
||||
nsDiskCacheDevice::Shutdown()
|
||||
{
|
||||
return Shutdown_Private(PR_TRUE);
|
||||
nsresult rv = Shutdown_Private(PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (mCacheDirectory) {
|
||||
// delete any trash files left-over before shutting down.
|
||||
nsCOMPtr<nsIFile> trashDir;
|
||||
GetTrashDir(mCacheDirectory, &trashDir);
|
||||
if (trashDir) {
|
||||
PRBool exists;
|
||||
if (NS_SUCCEEDED(trashDir->Exists(&exists)) && exists)
|
||||
DeleteDir(trashDir, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsDiskCacheDevice::Shutdown_Private(PRBool flush)
|
||||
{
|
||||
if (Initialized()) {
|
||||
if (Initialized()) {
|
||||
// check cache limits in case we need to evict.
|
||||
EvictDiskCacheEntries((PRInt32)mCacheCapacity);
|
||||
|
||||
|
@ -834,7 +849,7 @@ nsDiskCacheDevice::OpenDiskCache()
|
|||
rv = mCacheMap->Open(mCacheDirectory);
|
||||
// move "corrupt" caches to trash
|
||||
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||
rv = DeleteDir(mCacheDirectory, PR_TRUE);
|
||||
rv = DeleteDir(mCacheDirectory, PR_TRUE, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
exists = PR_FALSE;
|
||||
|
@ -858,7 +873,7 @@ nsDiskCacheDevice::OpenDiskCache()
|
|||
if (trashDir) {
|
||||
PRBool exists;
|
||||
if (NS_SUCCEEDED(trashDir->Exists(&exists)) && exists)
|
||||
DeleteDir(trashDir, PR_FALSE);
|
||||
DeleteDir(trashDir, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -876,8 +891,10 @@ nsDiskCacheDevice::ClearDiskCache()
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = DeleteDir(mCacheDirectory, PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
// If the disk cache directory is already gone, then it's not an error if
|
||||
// we fail to delete it ;-)
|
||||
rv = DeleteDir(mCacheDirectory, PR_TRUE, PR_FALSE);
|
||||
if (NS_FAILED(rv) && rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
|
||||
return rv;
|
||||
|
||||
return Init();
|
||||
|
|
Загрузка…
Ссылка в новой задаче