Bug 620660 - Ensure the disk-cache stays around until all cache-operations have finished. r=michal.novotny a=jst

This commit is contained in:
Bjarne 2011-01-20 13:41:10 -08:00
Родитель 6cf529ec88
Коммит c24a1e247d
3 изменённых файлов: 67 добавлений и 0 удалений

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

@ -268,6 +268,23 @@ private:
PRInt32 mSmartSize;
};
class nsBlockOnCacheThreadEvent : public nsRunnable {
public:
nsBlockOnCacheThreadEvent()
{
}
NS_IMETHOD Run()
{
mozilla::MonitorAutoEnter
autoMonitor(nsCacheService::gService->mMonitor);
#ifdef PR_LOGGING
CACHE_LOG_DEBUG(("nsBlockOnCacheThreadEvent [%p]\n", this));
#endif
autoMonitor.Notify();
return NS_OK;
}
};
nsresult
nsCacheProfilePrefObserver::Install()
@ -789,6 +806,33 @@ nsCacheService::DispatchToCacheIOThread(nsIRunnable* event)
return gService->mCacheIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
}
nsresult
nsCacheService::SyncWithCacheIOThread()
{
NS_ASSERTION(gService->mLockedThread == PR_GetCurrentThread(),
"not holding cache-lock");
if (!gService->mCacheIOThread) return NS_ERROR_NOT_AVAILABLE;
mozilla::MonitorAutoEnter autoMonitor(gService->mMonitor);
nsCOMPtr<nsIRunnable> event = new nsBlockOnCacheThreadEvent();
// dispatch event - it will notify the monitor when it's done
nsresult rv =
gService->mCacheIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
if (NS_FAILED(rv)) {
NS_WARNING("Failed dispatching block-event");
return NS_ERROR_UNEXPECTED;
}
Unlock();
// wait until notified, then return
rv = autoMonitor.Wait();
Lock();
return rv;
}
PRBool
nsCacheProfilePrefObserver::DiskCacheEnabled()
@ -942,6 +986,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheService, nsICacheService)
nsCacheService::nsCacheService()
: mLock(nsnull),
mMonitor("block-on-cache-monitor"),
mInitialized(PR_FALSE),
mEnableMemoryDevice(PR_TRUE),
mEnableDiskDevice(PR_TRUE),
@ -1046,6 +1091,10 @@ nsCacheService::Shutdown()
ClearDoomList();
ClearActiveEntries();
// Make sure to wait for any pending cache-operations before
// proceeding with destructive actions (bug #620660)
(void) SyncWithCacheIOThread();
// deallocate memory and disk caches
delete mMemoryDevice;
mMemoryDevice = nsnull;
@ -1920,6 +1969,10 @@ nsCacheService::OnProfileShutdown(PRBool cleanse)
gService->DoomActiveEntries();
gService->ClearDoomList();
// Make sure to wait for any pending cache-operations before
// proceeding with destructive actions (bug #620660)
(void) SyncWithCacheIOThread();
#ifdef NECKO_DISK_CACHE
if (gService->mDiskDevice && gService->mEnableDiskDevice) {
if (cleanse)

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

@ -56,6 +56,7 @@
#include "nsString.h"
#include "nsProxiedService.h"
#include "nsTArray.h"
#include "mozilla/Monitor.h"
class nsCacheRequest;
class nsCacheProfilePrefObserver;
@ -145,6 +146,11 @@ public:
static nsresult DispatchToCacheIOThread(nsIRunnable* event);
// Calling this method will block the calling thread until all pending
// events on the cache-io thread has finished. The calling thread must
// hold the cache-lock
static nsresult SyncWithCacheIOThread();
/**
* Methods called by nsCacheProfilePrefObserver
@ -171,6 +177,7 @@ private:
friend class nsOfflineCacheDevice;
friend class nsProcessRequestEvent;
friend class nsSetSmartSizeEvent;
friend class nsBlockOnCacheThreadEvent;
/**
* Internal Methods
@ -249,6 +256,8 @@ private:
PRLock * mLock;
mozilla::Monitor mMonitor;
#if defined(DEBUG)
PRThread * mLockedThread; // The thread holding mLock
#endif

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

@ -426,6 +426,11 @@ nsDiskCacheDevice::Shutdown_Private(PRBool flush)
// check cache limits in case we need to evict.
EvictDiskCacheEntries(mCacheCapacity);
// At this point there may be a number of pending cache-requests on the
// cache-io thread. Wait for all these to run before we wipe out our
// datastructures (see bug #620660)
(void) nsCacheService::SyncWithCacheIOThread();
// write out persistent information about the cache.
(void) mCacheMap.Close(flush);