Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Attributes
nsZipReaderCache Class Reference

#include <nsJAR.h>

Inheritance diagram for nsZipReaderCache:
Inheritance graph
[legend]
Collaboration diagram for nsZipReaderCache:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIZIPREADERCACHE
NS_DECL_NSIOBSERVER 
nsZipReaderCache ()
virtual ~nsZipReaderCache ()
nsresult ReleaseZip (nsJAR *reader)
void init (in unsigned long cacheSize)
 Initializes a new zip reader cache.
nsIZipReader getZip (in nsIFile zipFile)
 Returns a (possibly shared) nsIZipReader for an nsIFile.
void observe (in nsISupports aSubject, in string aTopic, in wstring aData)
 Observe will be called when there is a notification for the topic |aTopic|.

Protected Attributes

PRLockmLock
PRInt32 mCacheSize
nsSupportsHashtable mZips

Detailed Description

Definition at line 203 of file nsJAR.h.


Constructor & Destructor Documentation

Definition at line 1151 of file nsJAR.cpp.

  : mLock(nsnull),
    mZips(16)
#ifdef ZIP_CACHE_HIT_RATE
    ,
    mZipCacheLookups(0),
    mZipCacheHits(0),
    mZipCacheFlushes(0),
    mZipSyncMisses(0)
#endif
{
}

Definition at line 1191 of file nsJAR.cpp.

{
  if (mLock)
    PR_DestroyLock(mLock);
  mZips.Enumerate(DropZipReaderCache, nsnull);

#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);
#endif
}

Member Function Documentation

Returns a (possibly shared) nsIZipReader for an nsIFile.

void nsIZipReaderCache::init ( in unsigned long  cacheSize) [inherited]

Initializes a new zip reader cache.

Parameters:
cacheSize- the number of released entries to maintain before beginning to throw some out (note that the number of outstanding entries can be much greater than this number -- this is the count for those otherwise unused entries)
void nsIObserver::observe ( in nsISupports  aSubject,
in string  aTopic,
in wstring  aData 
) [inherited]

Observe will be called when there is a notification for the topic |aTopic|.

This assumes that the object implementing this interface has been registered with an observer service such as the nsIObserverService.

If you expect multiple topics/subjects, the impl is responsible for filtering.

You should not modify, add, remove, or enumerate notifications in the implemention of observe.

Parameters:
aSubject: Notification specific interface pointer.
aTopic: The notification topic or subject.
aData: Notification specific wide string. subject event.

Definition at line 1283 of file nsJAR.cpp.

{
  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();

  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;

#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));
  if (NS_FAILED(rv)) return rv;

  nsCAutoString path;
  rv = zipFile->GetNativePath(path);
  if (NS_FAILED(rv)) return rv;

  nsCStringKey key(path);
  PRBool removed = mZips.Remove(&key);  // Releases
  NS_ASSERTION(removed, "botched");

  return NS_OK;
}

Member Data Documentation

Definition at line 218 of file nsJAR.h.

Definition at line 217 of file nsJAR.h.

nsSupportsHashtable nsZipReaderCache::mZips [protected]

Definition at line 219 of file nsJAR.h.


The documentation for this class was generated from the following files: