fixes bug 329260 "Disk cache keeps emptying itself" r=biesi sr=bzbarsky

git-svn-id: svn://10.0.0.236/trunk@192099 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
darin%meer.net 2006-03-09 20:02:54 +00:00
parent 1e451feed6
commit 8abe3aabdb
8 changed files with 84 additions and 19 deletions

View File

@ -287,6 +287,10 @@ nsBaseChannel::GetStatus(nsresult *status)
NS_IMETHODIMP
nsBaseChannel::Cancel(nsresult status)
{
// Ignore redundant cancelation
if (NS_FAILED(mStatus))
return NS_OK;
mStatus = status;
if (mPump)

View File

@ -425,14 +425,14 @@ nsCacheEntryDescriptor::Close()
NS_IMETHODIMP
nsCacheEntryDescriptor::GetMetaDataElement(const char *key, char ** result)
nsCacheEntryDescriptor::GetMetaDataElement(const char *key, char **result)
{
NS_ENSURE_ARG_POINTER(key);
*result = nsnull;
nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_AVAILABLE);
if (!key | !result) return NS_ERROR_NULL_POINTER;
const char *value;
value = mCacheEntry->GetMetaDataElement(key);
@ -448,10 +448,10 @@ nsCacheEntryDescriptor::GetMetaDataElement(const char *key, char ** result)
NS_IMETHODIMP
nsCacheEntryDescriptor::SetMetaDataElement(const char *key, const char *value)
{
nsAutoLock lock(nsCacheService::ServiceLock());
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
NS_ENSURE_ARG_POINTER(key);
if (!key) return NS_ERROR_NULL_POINTER;
nsAutoLock lock(nsCacheService::ServiceLock());
NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_AVAILABLE);
// XXX allow null value, for clearing key?

View File

@ -218,24 +218,25 @@ nsDiskCacheBlockFile::WriteBlocks( void * buffer,
PRInt32 numBlocks)
{
// presume buffer != nsnull
if (!mFD) return NS_ERROR_NOT_AVAILABLE;
NS_ENSURE_TRUE(mFD, NS_ERROR_NOT_AVAILABLE);
nsresult rv = VerifyAllocation(startBlock, numBlocks);
if (NS_FAILED(rv)) return rv;
NS_ENSURE_SUCCESS(rv, rv);
// seek to block position
PRInt32 blockPos = kBitMapBytes + startBlock * mBlockSize;
PRInt32 filePos = PR_Seek(mFD, blockPos, PR_SEEK_SET);
if (filePos != blockPos) return NS_ERROR_UNEXPECTED;
NS_ENSURE_STATE(filePos == blockPos);
// write the blocks
PRInt32 bytesToWrite = numBlocks * mBlockSize;
PRInt32 bytesWritten = PR_Write(mFD, buffer, bytesToWrite);
if (bytesWritten < bytesToWrite) return NS_ERROR_UNEXPECTED;
NS_ENSURE_STATE(bytesWritten == bytesToWrite);
// write the bit map and flush the file
// XXX except we would take a severe performance hit
// XXX rv = FlushBitMap();
return rv;
return NS_OK;
}

View File

@ -390,6 +390,8 @@ nsDiskCacheDevice::Shutdown()
nsresult
nsDiskCacheDevice::Shutdown_Private(PRBool flush)
{
CACHE_LOG_DEBUG(("CACHE: disk Shutdown_Private [%u]\n", flush));
if (Initialized()) {
// check cache limits in case we need to evict.
EvictDiskCacheEntries(mCacheCapacity);
@ -476,6 +478,9 @@ nsDiskCacheDevice::DeactivateEntry(nsCacheEntry * entry)
NS_ASSERTION(binding, "DeactivateEntry: binding == nsnull");
if (!binding) return NS_ERROR_UNEXPECTED;
CACHE_LOG_DEBUG(("CACHE: disk DeactivateEntry [%p %x]\n",
entry, binding->mRecord.HashNumber()));
if (entry->IsDoomed()) {
// delete data, entry, record from disk for entry
rv = mCacheMap.DeleteStorage(&binding->mRecord);
@ -523,6 +528,9 @@ nsDiskCacheDevice::BindEntry(nsCacheEntry * entry)
record.SetHashNumber(nsDiskCache::Hash(entry->Key()->get()));
record.SetEvictionRank(ULONG_MAX - SecondsFromPRTime(PR_Now()));
CACHE_LOG_DEBUG(("CACHE: disk BindEntry [%p %x]\n",
entry, record.HashNumber()));
if (!entry->IsDoomed()) {
// if entry isn't doomed, add it to the cache map
rv = mCacheMap.AddRecord(&record, &oldRecord); // deletes old record, if any
@ -565,6 +573,8 @@ nsDiskCacheDevice::BindEntry(nsCacheEntry * entry)
void
nsDiskCacheDevice::DoomEntry(nsCacheEntry * entry)
{
CACHE_LOG_DEBUG(("CACHE: disk DoomEntry [%p]\n", entry));
nsDiskCacheBinding * binding = GetCacheEntryBinding(entry);
NS_ASSERTION(binding, "DoomEntry: binding == nsnull");
if (!binding) return;
@ -587,6 +597,9 @@ nsDiskCacheDevice::OpenInputStreamForEntry(nsCacheEntry * entry,
PRUint32 offset,
nsIInputStream ** result)
{
CACHE_LOG_DEBUG(("CACHE: disk OpenInputStreamForEntry [%p %x %u]\n",
entry, mode, offset));
NS_ENSURE_ARG_POINTER(entry);
NS_ENSURE_ARG_POINTER(result);
@ -612,6 +625,9 @@ nsDiskCacheDevice::OpenOutputStreamForEntry(nsCacheEntry * entry,
PRUint32 offset,
nsIOutputStream ** result)
{
CACHE_LOG_DEBUG(("CACHE: disk OpenOutputStreamForEntry [%p %x %u]\n",
entry, mode, offset));
NS_ENSURE_ARG_POINTER(entry);
NS_ENSURE_ARG_POINTER(result);
@ -681,6 +697,13 @@ nsDiskCacheDevice::GetFileForEntry(nsCacheEntry * entry,
nsresult
nsDiskCacheDevice::OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize)
{
CACHE_LOG_DEBUG(("CACHE: disk OnDataSizeChange [%p %d]\n",
entry, deltaSize));
// If passed a negative value, then there's nothing to do.
if (deltaSize < 0)
return NS_OK;
nsDiskCacheBinding * binding = GetCacheEntryBinding(entry);
NS_ASSERTION(binding, "OnDataSizeChange: binding == nsnull");
if (!binding) return NS_ERROR_UNEXPECTED;
@ -778,6 +801,8 @@ nsDiskCacheDevice::Visit(nsICacheVisitor * visitor)
nsresult
nsDiskCacheDevice::EvictEntries(const char * clientID)
{
CACHE_LOG_DEBUG(("CACHE: disk EvictEntries [%s]\n", clientID));
if (!Initialized()) return NS_ERROR_NOT_INITIALIZED;
nsresult rv;
@ -883,6 +908,11 @@ nsDiskCacheDevice::ClearDiskCache()
nsresult
nsDiskCacheDevice::EvictDiskCacheEntries(PRUint32 targetCapacity)
{
CACHE_LOG_DEBUG(("CACHE: disk EvictDiskCacheEntries [%u]\n",
targetCapacity));
NS_ASSERTION(targetCapacity > 0, "oops");
if (mCacheMap.TotalSize() < targetCapacity)
return NS_OK;

View File

@ -292,6 +292,7 @@ nsDiskCacheMap::GrowRecords()
{
if (mHeader.mRecordCount >= kMaxRecordCount)
return NS_OK;
CACHE_LOG_DEBUG(("CACHE: GrowRecords\n"));
// Resize the record array
PRUint32 newCount = mHeader.mRecordCount << 1;
@ -329,6 +330,7 @@ nsDiskCacheMap::ShrinkRecords()
{
if (mHeader.mRecordCount <= kMinRecordCount)
return NS_OK;
CACHE_LOG_DEBUG(("CACHE: ShrinkRecords\n"));
// Verify if we can shrink the record array: all buckets must be less than
// 1/2 filled
@ -371,6 +373,8 @@ nsresult
nsDiskCacheMap::AddRecord( nsDiskCacheRecord * mapRecord,
nsDiskCacheRecord * oldRecord)
{
CACHE_LOG_DEBUG(("CACHE: AddRecord [%x]\n", mapRecord->HashNumber()));
const PRUint32 hashNumber = mapRecord->HashNumber();
const PRUint32 bucketIndex = GetBucketIndex(hashNumber);
const PRUint32 count = mHeader.mBucketUsage[bucketIndex];
@ -416,6 +420,8 @@ nsDiskCacheMap::AddRecord( nsDiskCacheRecord * mapRecord,
nsresult
nsDiskCacheMap::UpdateRecord( nsDiskCacheRecord * mapRecord)
{
CACHE_LOG_DEBUG(("CACHE: UpdateRecord [%x]\n", mapRecord->HashNumber()));
const PRUint32 hashNumber = mapRecord->HashNumber();
const PRUint32 bucketIndex = GetBucketIndex(hashNumber);
nsDiskCacheRecord * records = GetFirstRecordInBucket(bucketIndex);
@ -438,6 +444,7 @@ NS_ASSERTION(mHeader.mEvictionRank[bucketIndex] == GetBucketRank(bucketIndex, 0)
return NS_OK;
}
}
NS_NOTREACHED("record not found");
return NS_ERROR_UNEXPECTED;
}
@ -462,6 +469,8 @@ nsDiskCacheMap::FindRecord( PRUint32 hashNumber, nsDiskCacheRecord * result)
nsresult
nsDiskCacheMap::DeleteRecord( nsDiskCacheRecord * mapRecord)
{
CACHE_LOG_DEBUG(("CACHE: DeleteRecord [%x]\n", mapRecord->HashNumber()));
const PRUint32 hashNumber = mapRecord->HashNumber();
const PRUint32 bucketIndex = GetBucketIndex(hashNumber);
nsDiskCacheRecord * records = GetFirstRecordInBucket(bucketIndex);
@ -646,6 +655,8 @@ nsDiskCacheMap::CacheFilesExist()
nsresult
nsDiskCacheMap::ReadDiskCacheEntry(nsDiskCacheRecord * record, nsDiskCacheEntry ** result)
{
CACHE_LOG_DEBUG(("CACHE: ReadDiskCacheEntry [%x]\n", record->HashNumber()));
nsresult rv = NS_ERROR_UNEXPECTED;
nsDiskCacheEntry * diskEntry = nsnull;
PRUint32 metaFile = record->MetaFile();
@ -715,6 +726,9 @@ exit:
nsresult
nsDiskCacheMap::WriteDiskCacheEntry(nsDiskCacheBinding * binding)
{
CACHE_LOG_DEBUG(("CACHE: WriteDiskCacheEntry [%x]\n",
binding->mRecord.HashNumber()));
nsresult rv = NS_OK;
nsDiskCacheEntry * diskEntry = CreateDiskCacheEntry(binding);
if (!diskEntry) return NS_ERROR_UNEXPECTED;
@ -809,6 +823,9 @@ exit:
nsresult
nsDiskCacheMap::ReadDataCacheBlocks(nsDiskCacheBinding * binding, char * buffer, PRUint32 size)
{
CACHE_LOG_DEBUG(("CACHE: ReadDataCacheBlocks [%x size=%u]\n",
binding->mRecord.HashNumber(), size));
nsresult rv;
PRUint32 fileIndex = binding->mRecord.DataFile();
PRUint32 blockSize = GetBlockSizeForIndex(fileIndex);
@ -830,6 +847,9 @@ nsDiskCacheMap::ReadDataCacheBlocks(nsDiskCacheBinding * binding, char * buffer,
nsresult
nsDiskCacheMap::WriteDataCacheBlocks(nsDiskCacheBinding * binding, char * buffer, PRUint32 size)
{
CACHE_LOG_DEBUG(("CACHE: WriteDataCacheBlocks [%x size=%u]\n",
binding->mRecord.HashNumber(), size));
nsresult rv;
// determine block file & number of blocks
@ -843,7 +863,7 @@ nsDiskCacheMap::WriteDataCacheBlocks(nsDiskCacheBinding * binding, char * buffer
startBlock = mBlockFile[fileIndex - 1].AllocateBlocks(blockCount);
rv = mBlockFile[fileIndex - 1].WriteBlocks(buffer, startBlock, blockCount);
if (NS_FAILED(rv)) return rv;
NS_ENSURE_SUCCESS(rv, rv);
IncrementTotalSize(blockCount, blockSize);
}
@ -852,8 +872,9 @@ nsDiskCacheMap::WriteDataCacheBlocks(nsDiskCacheBinding * binding, char * buffer
// update binding and cache map record
binding->mRecord.SetDataBlocks(fileIndex, startBlock, blockCount);
rv = UpdateRecord(&binding->mRecord);
NS_ENSURE_SUCCESS(rv, rv);
return rv;
return NS_OK;
}
@ -869,6 +890,9 @@ nsDiskCacheMap::DeleteStorage(nsDiskCacheRecord * record)
nsresult
nsDiskCacheMap::DeleteStorage(nsDiskCacheRecord * record, PRBool metaData)
{
CACHE_LOG_DEBUG(("CACHE: DeleteStorage [%x %u]\n", record->HashNumber(),
metaData));
nsresult rv = NS_ERROR_UNEXPECTED;
PRUint32 fileIndex = metaData ? record->MetaFile() : record->DataFile();
nsCOMPtr<nsIFile> file;

View File

@ -473,6 +473,8 @@ nsDiskCacheStreamIO::Flush()
{
NS_ASSERTION(mBinding, "oops");
CACHE_LOG_DEBUG(("CACHE: Flush [%x]\n", mBinding->mRecord.HashNumber()));
if (!mBufDirty)
return NS_OK;

View File

@ -1733,7 +1733,7 @@ nsHttpChannel::CloseCacheEntry(nsresult status)
// don't doom the cache entry if only reading from it...
if (NS_FAILED(status)
&& (mCacheAccess & nsICache::ACCESS_WRITE) && !mCachePump) {
LOG(("dooming cache entry!!"));
LOG((" dooming cache entry!!"));
rv = mCacheEntry->Doom();
}
@ -1839,7 +1839,11 @@ nsHttpChannel::InitCacheEntry()
// the meta data.
nsCAutoString head;
mResponseHead->Flatten(head, PR_TRUE);
return mCacheEntry->SetMetaDataElement("response-head", head.get());
rv = mCacheEntry->SetMetaDataElement("response-head", head.get());
if (NS_FAILED(rv)) return rv;
mOpenedCacheForWriting = PR_TRUE;
return NS_OK;
}
nsresult
@ -1888,8 +1892,6 @@ nsHttpChannel::InstallCacheListener(PRUint32 offset)
rv = mCacheEntry->OpenOutputStream(offset, getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
mOpenedCacheForWriting = PR_TRUE;
// XXX disk cache does not support overlapped i/o yet
#if 0
// Mark entry valid inorder to allow simultaneous reading...
@ -3108,6 +3110,10 @@ NS_IMETHODIMP
nsHttpChannel::Cancel(nsresult status)
{
LOG(("nsHttpChannel::Cancel [this=%x status=%x]\n", this, status));
if (mCanceled) {
LOG((" ignoring; already canceled\n"));
return NS_OK;
}
mCanceled = PR_TRUE;
mStatus = status;
if (mProxyRequest)

View File

@ -326,8 +326,6 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request,
{
nsresult rv;
LOG(("nsHttpHandler::AddStandardRequestHeaders\n"));
// Add the "User-Agent" header
rv = request->SetHeader(nsHttp::User_Agent, UserAgent());
if (NS_FAILED(rv)) return rv;