mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 01:57:00 +00:00
backing out earlier changes for 53312
This commit is contained in:
parent
d1f12ec2e5
commit
dabe025a7e
@ -148,7 +148,7 @@ DeleteManifestEntry(nsHashKey* aKey, void* aData, void* closure)
|
||||
// The following initialization makes a guess of 10 entries per jarfile.
|
||||
nsJAR::nsJAR(): mManifestData(nsnull, nsnull, DeleteManifestEntry, nsnull, 10),
|
||||
mParsedManifest(PR_FALSE), mGlobalStatus(nsIZipReader::NOT_SIGNED),
|
||||
mReleaseTime(PR_INTERVAL_NO_TIMEOUT), mCache(nsnull), mLock(nsnull)
|
||||
mReleaseTime(0), mCache(nsnull), mLock(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
@ -1101,18 +1101,17 @@ nsJARItem::GetCRC32(PRUint32 *aCrc32)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIZipReaderCache
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsZipReaderCache, nsIZipReaderCache, nsIObserver)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsZipReaderCache, nsIZipReaderCache)
|
||||
|
||||
nsZipReaderCache::nsZipReaderCache()
|
||||
: mLock(nsnull),
|
||||
mZips(16)
|
||||
mZips(16),
|
||||
#ifdef ZIP_CACHE_HIT_RATE
|
||||
,
|
||||
mZipCacheLookups(0),
|
||||
mZipCacheHits(0),
|
||||
mZipCacheFlushes(0),
|
||||
mZipSyncMisses(0)
|
||||
#endif
|
||||
mFreeCount(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
@ -1120,23 +1119,13 @@ nsZipReaderCache::nsZipReaderCache()
|
||||
NS_IMETHODIMP
|
||||
nsZipReaderCache::Init(PRUint32 cacheSize)
|
||||
{
|
||||
nsresult rv;
|
||||
#ifdef xDEBUG_warren
|
||||
mCacheSize = 1;//cacheSize; // XXX hack
|
||||
#else
|
||||
mCacheSize = cacheSize;
|
||||
mCacheSize = cacheSize;
|
||||
#endif
|
||||
|
||||
// Register as a memory pressure observer
|
||||
NS_WITH_SERVICE(nsIObserverService, os, NS_OBSERVERSERVICE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = os->AddObserver(this, NS_MEMORY_PRESSURE_TOPIC);
|
||||
}
|
||||
// ignore failure of the observer registration.
|
||||
|
||||
mLock = PR_NewLock();
|
||||
return mLock ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
}
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
@ -1149,21 +1138,14 @@ DropZipReaderCache(nsHashKey *aKey, void *aData, void* closure)
|
||||
|
||||
nsZipReaderCache::~nsZipReaderCache()
|
||||
{
|
||||
nsresult rv;
|
||||
if (mLock)
|
||||
PR_DestroyLock(mLock);
|
||||
mZips.Enumerate(DropZipReaderCache, nsnull);
|
||||
// Unregister this memory pressure observer
|
||||
NS_WITH_SERVICE(nsIObserverService, os, NS_OBSERVERSERVICE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = os->RemoveObserver(this, NS_MEMORY_PRESSURE_TOPIC);
|
||||
}
|
||||
|
||||
#ifdef ZIP_CACHE_HIT_RATE
|
||||
printf("nsZipReaderCache size=%d hits=%d lookups=%d rate=%f%% flushes=%d missed %d\n",
|
||||
mCacheSize, mZipCacheHits, mZipCacheLookups,
|
||||
(float)mZipCacheHits / mZipCacheLookups,
|
||||
mZipCacheFlushes, mZipSyncMisses);
|
||||
printf("nsZipReaderCache size=%d hits=%d lookups=%d rate=%f%% flushes=%d\n",
|
||||
mZipCacheHits, mZipCacheLookups, (float)mZipCacheHits / mZipCacheLookups,
|
||||
mZipCacheFlushes);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1202,7 +1184,11 @@ nsZipReaderCache::GetZip(nsIFile* zipFile, nsIZipReader* *result)
|
||||
#ifdef ZIP_CACHE_HIT_RATE
|
||||
mZipCacheHits++;
|
||||
#endif
|
||||
zip->ClearReleaseTime();
|
||||
if (zip->GetReleaseTime() != PR_INTERVAL_NO_TIMEOUT) {
|
||||
// this was an otherwise-free entry, so decrement our free counter
|
||||
NS_ASSERTION(mFreeCount > 0, "mFreeCount screwed up");
|
||||
mFreeCount--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
zip = new nsJAR();
|
||||
@ -1245,72 +1231,32 @@ FindOldestZip(nsHashKey *aKey, void *aData, void* closure)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
struct ZipFindData {nsJAR* zip; PRBool found;};
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
FindZip(nsHashKey *aKey, void *aData, void* closure)
|
||||
{
|
||||
ZipFindData* find_data = (ZipFindData*)closure;
|
||||
|
||||
if (find_data->zip == (nsJAR*)aData) {
|
||||
find_data->found = PR_TRUE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsZipReaderCache::ReleaseZip(nsJAR* zip)
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
// It is possible that two thread compete for this zip. The dangerous
|
||||
// case is where one thread Releases the zip and discovers that the ref
|
||||
// count has gone to one. Before it can call this ReleaseZip method
|
||||
// another thread calls our GetZip method. The ref count goes to two. That
|
||||
// second thread then Releases the zip and the ref coutn goes to one. It
|
||||
// Then tries to enter this ReleaseZip method and blocks while the first
|
||||
// thread is still here. The first thread continues and remove the zip from
|
||||
// the cache and calls its Release method sending the ref count to 0 and
|
||||
// deleting the zip. However, the second thread is still blocked at the
|
||||
// start of ReleaseZip, but the 'zip' param now hold a reference to a
|
||||
// deleted zip!
|
||||
//
|
||||
// So, we are going to try safegaurding here by searching our hashtable while
|
||||
// locked here for the zip. We return fast if it is not found.
|
||||
|
||||
ZipFindData find_data = {zip, PR_FALSE};
|
||||
mZips.Enumerate(FindZip, &find_data);
|
||||
if (!find_data.found) {
|
||||
#ifdef ZIP_CACHE_HIT_RATE
|
||||
mZipSyncMisses++;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
zip->SetReleaseTime();
|
||||
|
||||
mFreeCount++;
|
||||
if (mZips.Count() <= mCacheSize)
|
||||
return NS_OK;
|
||||
|
||||
nsJAR* oldest = nsnull;
|
||||
mZips.Enumerate(FindOldestZip, &oldest);
|
||||
|
||||
// Because of the craziness above it is possible that there is no zip that
|
||||
// needs removing.
|
||||
if (!oldest)
|
||||
return NS_OK;
|
||||
if (mFreeCount == 1) {
|
||||
// then this is our guy -- no need to search for the oldest
|
||||
oldest = zip;
|
||||
}
|
||||
else {
|
||||
mZips.Enumerate(FindOldestZip, &oldest);
|
||||
}
|
||||
NS_ASSERTION(oldest, "wacked");
|
||||
|
||||
#ifdef ZIP_CACHE_HIT_RATE
|
||||
mZipCacheFlushes++;
|
||||
#endif
|
||||
|
||||
// Clear the cache pointer in case we gave out this oldest guy while
|
||||
// his Release call was being made. Otherwise we could nest on ReleaseZip
|
||||
// when the second owner calls Release and we are still here in this lock.
|
||||
oldest->SetZipReaderCache(nsnull);
|
||||
|
||||
// remove from hashtable
|
||||
nsCOMPtr<nsIFile> zipFile;
|
||||
rv = oldest->GetFile(getter_AddRefs(zipFile));
|
||||
@ -1324,48 +1270,6 @@ nsZipReaderCache::ReleaseZip(nsJAR* zip)
|
||||
PRBool removed = mZips.Remove(&key); // Releases
|
||||
NS_ASSERTION(removed, "botched");
|
||||
|
||||
#ifdef xDEBUG_jband
|
||||
printf("dumped %s from the jar cache\n", (const char*) path);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
FindUnreferencedZip(nsHashKey *aKey, void *aData, void* closure)
|
||||
{
|
||||
nsHashKey** unrefKeyPtr = (nsHashKey**)closure;
|
||||
nsJAR* current = (nsJAR*)aData;
|
||||
|
||||
if (current->GetReleaseTime() != PR_INTERVAL_NO_TIMEOUT) {
|
||||
*unrefKeyPtr = aKey;
|
||||
current->SetZipReaderCache(nsnull);
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsZipReaderCache::Observe(nsISupports *aSubject,
|
||||
const PRUnichar *aTopic,
|
||||
const PRUnichar *aSomeData)
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
while (PR_TRUE)
|
||||
{
|
||||
nsHashKey* unreferenced = nsnull;
|
||||
mZips.Enumerate(FindUnreferencedZip, &unreferenced);
|
||||
if ( ! unreferenced )
|
||||
break;
|
||||
PRBool removed = mZips.Remove(unreferenced); // Releases
|
||||
NS_ASSERTION(removed, "botched");
|
||||
|
||||
#ifdef xDEBUG_jband
|
||||
printf("flushed something from the jar cache\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include "zipfile.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsISignatureVerifier.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
||||
class nsIInputStream;
|
||||
class nsJARManifestItem;
|
||||
@ -85,11 +84,10 @@ class nsJAR : public nsIZipReader
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
PRIntervalTime GetReleaseTime() {
|
||||
if (mRefCnt == 1)
|
||||
return mReleaseTime;
|
||||
}
|
||||
|
||||
PRBool IsReleased() {
|
||||
return mReleaseTime != PR_INTERVAL_NO_TIMEOUT;
|
||||
else
|
||||
return PR_INTERVAL_NO_TIMEOUT;
|
||||
}
|
||||
|
||||
void SetReleaseTime() {
|
||||
@ -182,16 +180,15 @@ protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(DEBUG_warren) || defined(DEBUG_jband)
|
||||
#ifdef DEBUG_warren
|
||||
#define ZIP_CACHE_HIT_RATE
|
||||
#endif
|
||||
|
||||
class nsZipReaderCache : public nsIZipReaderCache, public nsIObserver
|
||||
class nsZipReaderCache : public nsIZipReaderCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIZIPREADERCACHE
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
nsZipReaderCache();
|
||||
virtual ~nsZipReaderCache();
|
||||
@ -205,12 +202,12 @@ protected:
|
||||
PRLock* mLock;
|
||||
PRInt32 mCacheSize;
|
||||
nsSupportsHashtable mZips;
|
||||
PRUint32 mFreeCount;
|
||||
|
||||
#ifdef ZIP_CACHE_HIT_RATE
|
||||
PRUint32 mZipCacheLookups;
|
||||
PRUint32 mZipCacheHits;
|
||||
PRUint32 mZipCacheFlushes;
|
||||
PRUint32 mZipSyncMisses;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user