Backed out changeset d8543551f12e (bug 913808)

This commit is contained in:
Ed Morley 2014-03-05 17:25:04 +00:00
Родитель fa2daad1c0
Коммит d324b8dded
18 изменённых файлов: 395 добавлений и 592 удалений

Просмотреть файл

@ -80,6 +80,80 @@ bool CacheEntriesEnumerator::HasMore()
return !!mCurrentFile;
}
namespace { // anon
class FileConsumer : public CacheFileListener
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
nsresult Init(nsCSubstring const & aKey,
CacheEntriesEnumeratorCallback* aCallback);
virtual ~FileConsumer() {}
private:
NS_IMETHOD OnFileReady(nsresult aResult, bool aIsNew);
NS_IMETHOD OnFileDoomed(nsresult aResult) { return NS_OK; }
nsRefPtr<CacheFile> mFile;
nsRefPtr<CacheEntriesEnumeratorCallback> mCallback;
};
nsresult FileConsumer::Init(const nsCSubstring &aKey,
CacheEntriesEnumeratorCallback *aCallback)
{
mCallback = aCallback;
mFile = new CacheFile();
nsresult rv = mFile->Init(aKey, false, false, false, true, this);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP FileConsumer::OnFileReady(nsresult aResult, bool aIsNew)
{
//MOZ_ASSERT(!aIsNew);
if (NS_FAILED(aResult)) {
mCallback->OnFile(nullptr);
}
else {
mCallback->OnFile(mFile);
}
return NS_OK;
}
NS_IMPL_ISUPPORTS1(FileConsumer, CacheFileListener);
} // anon
nsresult CacheEntriesEnumerator::GetNextCacheFile(CacheEntriesEnumeratorCallback* aCallback)
{
#ifdef DEBUG
MOZ_ASSERT(mThreadCheck == NS_GetCurrentThread());
#endif
nsresult rv;
NS_ENSURE_TRUE(mCurrentFile, NS_ERROR_UNEXPECTED);
nsAutoCString key;
rv = mCurrentFile->GetNativeLeafName(key);
mCurrentFile = nullptr;
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<FileConsumer> consumer = new FileConsumer();
rv = consumer->Init(key, aCallback);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult CacheEntriesEnumerator::GetNextFile(nsIFile** aFile)
{
#ifdef DEBUG
@ -92,5 +166,21 @@ nsresult CacheEntriesEnumerator::GetNextFile(nsIFile** aFile)
return NS_OK;
}
nsresult CacheEntriesEnumerator::GetCacheFileFromFile(nsIFile* aFile,
CacheEntriesEnumeratorCallback* aCallback)
{
nsresult rv;
nsAutoCString key;
rv = aFile->GetNativeLeafName(key);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<FileConsumer> consumer = new FileConsumer();
rv = consumer->Init(key, aCallback);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
} // net
} // mozilla

Просмотреть файл

@ -30,7 +30,9 @@ public:
~CacheEntriesEnumerator();
bool HasMore();
nsresult GetNextCacheFile(CacheEntriesEnumeratorCallback* aCallback);
nsresult GetNextFile(nsIFile** aFile);
nsresult GetCacheFileFromFile(nsIFile* aFile, CacheEntriesEnumeratorCallback* aCallback);
protected:
friend class CacheFileIOManager;

Просмотреть файл

@ -319,6 +319,7 @@ bool CacheEntry::Load(bool aTruncate, bool aPriority)
aTruncate,
!mUseDisk,
aPriority,
false /* key is not a hash */,
directLoad ? nullptr : this);
}
@ -836,17 +837,6 @@ bool CacheEntry::IsReferenced() const
return mHandlersCount > 0;
}
bool CacheEntry::IsFileDoomed()
{
mozilla::MutexAutoLock lock(mLock);
if (NS_SUCCEEDED(mFileStatus)) {
return mFile->IsDoomed();
}
return false;
}
uint32_t CacheEntry::GetMetadataMemoryConsumption()
{
NS_ENSURE_SUCCESS(mFileStatus, 0);

Просмотреть файл

@ -70,7 +70,6 @@ public:
bool UsingDisk() const;
bool SetUsingDisk(bool aUsingDisk);
bool IsReferenced() const;
bool IsFileDoomed();
// Methods for entry management (eviction from memory),
// called only on the management thread.

Просмотреть файл

@ -195,15 +195,19 @@ CacheFile::Init(const nsACString &aKey,
bool aCreateNew,
bool aMemoryOnly,
bool aPriority,
bool aKeyIsHash,
CacheFileListener *aCallback)
{
MOZ_ASSERT(!mListener);
MOZ_ASSERT(!mHandle);
MOZ_ASSERT(!(aCreateNew && aKeyIsHash));
MOZ_ASSERT(!(aMemoryOnly && aKeyIsHash));
nsresult rv;
mKey = aKey;
mMemoryOnly = aMemoryOnly;
mKeyIsHash = aKeyIsHash;
LOG(("CacheFile::Init() [this=%p, key=%s, createNew=%d, memoryOnly=%d, "
"listener=%p]", this, mKey.get(), aCreateNew, aMemoryOnly, aCallback));
@ -211,6 +215,7 @@ CacheFile::Init(const nsACString &aKey,
if (mMemoryOnly) {
MOZ_ASSERT(!aCallback);
MOZ_ASSERT(!mKeyIsHash);
mMetadata = new CacheFileMetadata(mKey);
mReady = true;
mDataSize = mMetadata->Offset();
@ -223,6 +228,7 @@ CacheFile::Init(const nsACString &aKey,
flags = CacheFileIOManager::CREATE_NEW;
// make sure we can use this entry immediately
MOZ_ASSERT(!mKeyIsHash);
mMetadata = new CacheFileMetadata(mKey);
mReady = true;
mDataSize = mMetadata->Offset();
@ -230,33 +236,37 @@ CacheFile::Init(const nsACString &aKey,
else {
flags = CacheFileIOManager::CREATE;
// Have a look into index and change to CREATE_NEW when we are sure
// that the entry does not exist.
CacheIndex::EntryStatus status;
rv = CacheIndex::HasEntry(mKey, &status);
if (status == CacheIndex::DOES_NOT_EXIST) {
LOG(("CacheFile::Init() - Forcing CREATE_NEW flag since we don't have"
" this entry according to index"));
flags = CacheFileIOManager::CREATE_NEW;
if (!mKeyIsHash) {
// Have a look into index and change to CREATE_NEW when we are sure
// that the entry does not exist.
CacheIndex::EntryStatus status;
rv = CacheIndex::HasEntry(mKey, &status);
if (status == CacheIndex::DOES_NOT_EXIST) {
LOG(("CacheFile::Init() - Forcing CREATE_NEW flag since we don't have"
" this entry according to index"));
flags = CacheFileIOManager::CREATE_NEW;
// make sure we can use this entry immediately
mMetadata = new CacheFileMetadata(mKey);
mReady = true;
mDataSize = mMetadata->Offset();
// make sure we can use this entry immediately
mMetadata = new CacheFileMetadata(mKey);
mReady = true;
mDataSize = mMetadata->Offset();
// Notify callback now and don't store it in mListener, no further
// operation can change the result.
nsRefPtr<NotifyCacheFileListenerEvent> ev;
ev = new NotifyCacheFileListenerEvent(aCallback, NS_OK, true);
rv = NS_DispatchToCurrentThread(ev);
NS_ENSURE_SUCCESS(rv, rv);
// Notify callback now and don't store it in mListener, no further
// operation can change the result.
nsRefPtr<NotifyCacheFileListenerEvent> ev;
ev = new NotifyCacheFileListenerEvent(aCallback, NS_OK, true);
rv = NS_DispatchToCurrentThread(ev);
NS_ENSURE_SUCCESS(rv, rv);
aCallback = nullptr;
aCallback = nullptr;
}
}
}
if (aPriority)
flags |= CacheFileIOManager::PRIORITY;
if (aKeyIsHash)
flags |= CacheFileIOManager::NOHASH;
mOpeningFile = true;
mListener = aCallback;
@ -280,6 +290,7 @@ CacheFile::Init(const nsACString &aKey,
"initializing entry as memory-only. [this=%p]", this));
mMemoryOnly = true;
MOZ_ASSERT(!mKeyIsHash);
mMetadata = new CacheFileMetadata(mKey);
mReady = true;
mDataSize = mMetadata->Offset();
@ -477,6 +488,7 @@ CacheFile::OnFileOpened(CacheFileHandle *aHandle, nsresult aResult)
this));
mMemoryOnly = true;
MOZ_ASSERT(!mKeyIsHash);
mMetadata = new CacheFileMetadata(mKey);
mReady = true;
mDataSize = mMetadata->Offset();
@ -518,7 +530,7 @@ CacheFile::OnFileOpened(CacheFileHandle *aHandle, nsresult aResult)
MOZ_ASSERT(!mMetadata);
MOZ_ASSERT(mListener);
mMetadata = new CacheFileMetadata(mHandle, mKey);
mMetadata = new CacheFileMetadata(mHandle, mKey, mKeyIsHash);
rv = mMetadata->ReadMetadata(this);
if (NS_FAILED(rv)) {
@ -553,6 +565,13 @@ CacheFile::OnMetadataRead(nsresult aResult)
bool isNew = false;
if (NS_SUCCEEDED(aResult)) {
MOZ_ASSERT(!mMetadata->KeyIsHash());
if (mKeyIsHash) {
mMetadata->GetKey(mKey);
mKeyIsHash = false;
}
mReady = true;
mDataSize = mMetadata->Offset();
if (mDataSize == 0 && mMetadata->ElementsSize() == 0) {
@ -736,10 +755,6 @@ CacheFile::Doom(CacheFileListener *aCallback)
return NS_ERROR_FILE_NOT_FOUND;
}
if (mHandle && mHandle->IsDoomed()) {
return NS_ERROR_FILE_NOT_FOUND;
}
nsCOMPtr<CacheFileIOListener> listener;
if (aCallback || !mHandle) {
listener = new DoomFileHelper(aCallback);
@ -1350,17 +1365,6 @@ CacheFile::DataSize(int64_t* aSize)
return true;
}
bool
CacheFile::IsDoomed()
{
CacheFileAutoLock lock(this);
if (!mHandle)
return false;
return mHandle->IsDoomed();
}
bool
CacheFile::IsDirty()
{

Просмотреть файл

@ -56,6 +56,7 @@ public:
bool aCreateNew,
bool aMemoryOnly,
bool aPriority,
bool aKeyIsHash,
CacheFileListener *aCallback);
NS_IMETHOD OnChunkRead(nsresult aResult, CacheFileChunk *aChunk);
@ -97,7 +98,6 @@ public:
bool DataSize(int64_t* aSize);
void Key(nsACString& aKey) { aKey = mKey; }
bool IsDoomed();
private:
friend class CacheFileIOManager;
@ -165,6 +165,7 @@ private:
bool mDataAccessed;
bool mDataIsDirty;
bool mWritingMetadata;
bool mKeyIsHash;
nsresult mStatus;
int64_t mDataSize;
nsCString mKey;

Просмотреть файл

@ -9,10 +9,8 @@
#include "CacheHashUtils.h"
#include "CacheStorageService.h"
#include "CacheIndex.h"
#include "CacheFileUtils.h"
#include "nsThreadUtils.h"
#include "CacheFile.h"
#include "CacheObserver.h"
#include "nsIFile.h"
#include "mozilla/Telemetry.h"
#include "mozilla/DebugOnly.h"
@ -38,7 +36,6 @@ namespace net {
#define kOpenHandlesLimit 64
#define kMetadataWriteDelay 5000
#define kEvictionLoopLimit 40 // in milliseconds
bool
CacheFileHandle::DispatchRelease()
@ -483,7 +480,32 @@ public:
if (mTarget) {
mRV = NS_OK;
if (!(mFlags & CacheFileIOManager::SPECIAL_FILE)) {
if (mFlags & CacheFileIOManager::SPECIAL_FILE) {
}
else if (mFlags & CacheFileIOManager::NOHASH) {
nsACString::const_char_iterator begin, end;
begin = mKey.BeginReading();
end = mKey.EndReading();
uint32_t i = 0;
while (begin != end && i < (SHA1Sum::HashSize << 1)) {
if (!(i & 1))
mHash[i >> 1] = 0;
uint8_t shift = (i & 1) ? 0 : 4;
if (*begin >= '0' && *begin <= '9')
mHash[i >> 1] |= (*begin - '0') << shift;
else if (*begin >= 'A' && *begin <= 'F')
mHash[i >> 1] |= (*begin - 'A' + 10) << shift;
else
break;
++i;
++begin;
}
if (i != (SHA1Sum::HashSize << 1) || begin != end)
mRV = NS_ERROR_INVALID_ARG;
}
else {
SHA1Sum sum;
sum.update(mKey.BeginReading(), mKey.Length());
sum.finish(mHash);
@ -1021,7 +1043,6 @@ NS_IMPL_ISUPPORTS1(CacheFileIOManager, nsITimerCallback)
CacheFileIOManager::CacheFileIOManager()
: mShuttingDown(false)
, mTreeCreated(false)
, mOverLimitEvicting(false)
{
LOG(("CacheFileIOManager::CacheFileIOManager [this=%p]", this));
MOZ_COUNT_CTOR(CacheFileIOManager);
@ -1760,7 +1781,6 @@ CacheFileIOManager::WriteInternal(CacheFileHandle *aHandle, int64_t aOffset,
if (!aHandle->IsDoomed() && !aHandle->IsSpecialFile()) {
uint32_t size = aHandle->FileSizeInK();
CacheIndex::UpdateEntry(aHandle->Hash(), nullptr, nullptr, &size);
EvictIfOverLimitInternal();
}
}
@ -1841,20 +1861,6 @@ CacheFileIOManager::DoomFileInternal(CacheFileHandle *aHandle)
CacheIndex::RemoveEntry(aHandle->Hash());
aHandle->mIsDoomed = true;
if (!aHandle->IsSpecialFile()) {
nsRefPtr<CacheStorageService> storageService = CacheStorageService::Self();
if (storageService) {
nsAutoCString url;
nsCOMPtr<nsILoadContextInfo> info;
rv = CacheFileUtils::ParseKey(aHandle->Key(), getter_AddRefs(info), &url);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (NS_SUCCEEDED(rv)) {
storageService->CacheFileDoomed(info, url);
}
}
}
return NS_OK;
}
@ -2152,181 +2158,6 @@ CacheFileIOManager::RenameFileInternal(CacheFileHandle *aHandle,
return NS_OK;
}
nsresult
CacheFileIOManager::EvictIfOverLimit()
{
LOG(("CacheFileIOManager::EvictIfOverLimit()"));
nsresult rv;
nsRefPtr<CacheFileIOManager> ioMan = gInstance;
if (!ioMan)
return NS_ERROR_NOT_INITIALIZED;
nsCOMPtr<nsIRunnable> ev;
ev = NS_NewRunnableMethod(ioMan,
&CacheFileIOManager::EvictIfOverLimitInternal);
rv = ioMan->mIOThread->Dispatch(ev, CacheIOThread::EVICT);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
CacheFileIOManager::EvictIfOverLimitInternal()
{
LOG(("CacheFileIOManager::EvictIfOverLimitInternal()"));
nsresult rv;
MOZ_ASSERT(mIOThread->IsCurrentThread());
if (mShuttingDown)
return NS_ERROR_NOT_INITIALIZED;
if (mOverLimitEvicting) {
LOG(("CacheFileIOManager::EvictIfOverLimitInternal() - Eviction already "
"running."));
return NS_OK;
}
uint32_t cacheUsage;
rv = CacheIndex::GetCacheSize(&cacheUsage);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t cacheLimit = CacheObserver::DiskCacheCapacity() >> 10;
if (cacheUsage <= cacheLimit) {
LOG(("CacheFileIOManager::EvictIfOverLimitInternal() - Cache size under "
"limit. [cacheSize=%u, limit=%u]", cacheUsage, cacheLimit));
return NS_OK;
}
LOG(("CacheFileIOManager::EvictIfOverLimitInternal() - Cache size exceeded "
"limit. Starting overlimit eviction. [cacheSize=%u, limit=%u]",
cacheUsage, cacheLimit));
nsCOMPtr<nsIRunnable> ev;
ev = NS_NewRunnableMethod(this,
&CacheFileIOManager::OverLimitEvictionInternal);
rv = mIOThread->Dispatch(ev, CacheIOThread::EVICT);
NS_ENSURE_SUCCESS(rv, rv);
mOverLimitEvicting = true;
return NS_OK;
}
nsresult
CacheFileIOManager::OverLimitEvictionInternal()
{
LOG(("CacheFileIOManager::OverLimitEvictionInternal()"));
nsresult rv;
// mOverLimitEvicting is accessed only on IO thread, so we can set it to false
// here and set ti to true again once we dispatch another event that will
// continue with the eviction. The reason why we do so is that we can fail
// early anywhere in this method and the variable will contain a correct
// value. Otherwise we would need to set it to false on every failing place.
mOverLimitEvicting = false;
if (mShuttingDown)
return NS_ERROR_NOT_INITIALIZED;
TimeStamp start;
while (true) {
uint32_t cacheUsage;
rv = CacheIndex::GetCacheSize(&cacheUsage);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t cacheLimit = CacheObserver::DiskCacheCapacity() >> 10;
if (cacheUsage <= cacheLimit) {
LOG(("CacheFileIOManager::OverLimitEvictionInternal() - Cache size under "
"limit. [cacheSize=%u, limit=%u]", cacheUsage, cacheLimit));
return NS_OK;
}
LOG(("CacheFileIOManager::OverLimitEvictionInternal() - Cache size over "
"limit. [cacheSize=%u, limit=%u]", cacheUsage, cacheLimit));
if (start.IsNull()) {
start = TimeStamp::NowLoRes();
} else {
TimeDuration elapsed = TimeStamp::NowLoRes() - start;
if (elapsed.ToMilliseconds() >= kEvictionLoopLimit) {
LOG(("CacheFileIOManager::OverLimitEvictionInternal() - Breaking loop "
"after %u ms.", static_cast<uint32_t>(elapsed.ToMilliseconds())));
break;
}
}
SHA1Sum::Hash hash;
uint32_t cnt;
static uint32_t consecutiveFailures = 0;
rv = CacheIndex::GetEntryForEviction(&hash, &cnt);
NS_ENSURE_SUCCESS(rv, rv);
rv = DoomFileByKeyInternal(&hash);
if (NS_SUCCEEDED(rv)) {
consecutiveFailures = 0;
}
else if (rv == NS_ERROR_NOT_AVAILABLE) {
LOG(("CacheFileIOManager::OverLimitEvictionInternal() - "
"DoomFileByKeyInternal() failed. [rv=0x%08x]", rv));
// TODO index is outdated, start update
// Make sure index won't return the same entry again
CacheIndex::RemoveEntry(&hash);
consecutiveFailures = 0;
}
else {
// This shouldn't normally happen, but the eviction must not fail
// completely if we ever encounter this problem.
NS_WARNING("CacheFileIOManager::OverLimitEvictionInternal() - Unexpected "
"failure of DoomFileByKeyInternal()");
LOG(("CacheFileIOManager::OverLimitEvictionInternal() - "
"DoomFileByKeyInternal() failed. [rv=0x%08x]", rv));
// Normally, CacheIndex::UpdateEntry() is called only to update newly
// created/opened entries which are always fresh and UpdateEntry() expects
// and checks this flag. The way we use UpdateEntry() here is a kind of
// hack and we must make sure the flag is set by calling
// EnsureEntryExists().
rv = CacheIndex::EnsureEntryExists(&hash);
NS_ENSURE_SUCCESS(rv, rv);
// Move the entry at the end of both lists to make sure we won't end up
// failing on one entry forever.
uint32_t frecency = 0;
uint32_t expTime = nsICacheEntry::NO_EXPIRATION_TIME;
rv = CacheIndex::UpdateEntry(&hash, &frecency, &expTime, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
consecutiveFailures++;
if (consecutiveFailures >= cnt) {
// This doesn't necessarily mean that we've tried to doom every entry
// but we've reached a sane number of tries. It is likely that another
// eviction will start soon. And as said earlier, this normally doesn't
// happen at all.
return NS_OK;
}
}
}
nsCOMPtr<nsIRunnable> ev;
ev = NS_NewRunnableMethod(this,
&CacheFileIOManager::OverLimitEvictionInternal);
rv = mIOThread->Dispatch(ev, CacheIOThread::EVICT);
NS_ENSURE_SUCCESS(rv, rv);
mOverLimitEvicting = true;
return NS_OK;
}
nsresult
CacheFileIOManager::InitIndexEntry(CacheFileHandle *aHandle,
uint32_t aAppId,

Просмотреть файл

@ -195,7 +195,8 @@ public:
CREATE = 1U,
CREATE_NEW = 2U,
PRIORITY = 4U,
SPECIAL_FILE = 8U
NOHASH = 8U,
SPECIAL_FILE = 16U
};
CacheFileIOManager();
@ -238,8 +239,6 @@ public:
static nsresult RenameFile(CacheFileHandle *aHandle,
const nsACString &aNewName,
CacheFileIOListener *aCallback);
static nsresult EvictIfOverLimit();
static nsresult InitIndexEntry(CacheFileHandle *aHandle,
uint32_t aAppId,
bool aAnonymous,
@ -300,8 +299,6 @@ private:
int64_t aTruncatePos, int64_t aEOFPos);
nsresult RenameFileInternal(CacheFileHandle *aHandle,
const nsACString &aNewName);
nsresult EvictIfOverLimitInternal();
nsresult OverLimitEvictionInternal();
nsresult CreateFile(CacheFileHandle *aHandle);
static void HashToStr(const SHA1Sum::Hash *aHash, nsACString &_retval);
@ -328,7 +325,6 @@ private:
nsTArray<nsRefPtr<CacheFileHandle> > mSpecialHandles;
nsTArray<nsRefPtr<CacheFile> > mScheduledMetadataWrites;
nsCOMPtr<nsITimer> mMetadataWritesTimer;
bool mOverLimitEvicting;
};
} // net

Просмотреть файл

@ -9,7 +9,6 @@
#include "nsICacheEntry.h"
#include "CacheHashUtils.h"
#include "CacheFileChunk.h"
#include "CacheFileUtils.h"
#include "nsILoadContextInfo.h"
#include "../cache/nsCacheUtils.h"
#include "nsIFile.h"
@ -26,8 +25,9 @@ namespace net {
NS_IMPL_ISUPPORTS1(CacheFileMetadata, CacheFileIOListener)
CacheFileMetadata::CacheFileMetadata(CacheFileHandle *aHandle, const nsACString &aKey)
CacheFileMetadata::CacheFileMetadata(CacheFileHandle *aHandle, const nsACString &aKey, bool aKeyIsHash)
: mHandle(aHandle)
, mKeyIsHash(aKeyIsHash)
, mHashArray(nullptr)
, mHashArraySize(0)
, mHashCount(0)
@ -48,10 +48,11 @@ CacheFileMetadata::CacheFileMetadata(CacheFileHandle *aHandle, const nsACString
memset(&mMetaHdr, 0, sizeof(CacheFileMetadataHeader));
mMetaHdr.mExpirationTime = nsICacheEntry::NO_EXPIRATION_TIME;
mKey = aKey;
DebugOnly<nsresult> rv;
rv = ParseKey(aKey);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (!aKeyIsHash) {
DebugOnly<nsresult> rv;
rv = ParseKey(aKey);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
}
CacheFileMetadata::~CacheFileMetadata()
@ -78,6 +79,7 @@ CacheFileMetadata::~CacheFileMetadata()
CacheFileMetadata::CacheFileMetadata(const nsACString &aKey)
: mHandle(nullptr)
, mKeyIsHash(false)
, mHashArray(nullptr)
, mHashArraySize(0)
, mHashCount(0)
@ -108,6 +110,7 @@ CacheFileMetadata::CacheFileMetadata(const nsACString &aKey)
CacheFileMetadata::CacheFileMetadata()
: mHandle(nullptr)
, mKeyIsHash(false)
, mHashArray(nullptr)
, mHashArraySize(0)
, mHashCount(0)
@ -144,6 +147,12 @@ CacheFileMetadata::GetKey(nsACString &_retval)
return NS_OK;
}
bool
CacheFileMetadata::KeyIsHash()
{
return mKeyIsHash;
}
nsresult
CacheFileMetadata::ReadMetadata(CacheFileMetadataListener *aListener)
{
@ -160,6 +169,14 @@ CacheFileMetadata::ReadMetadata(CacheFileMetadataListener *aListener)
MOZ_ASSERT(size != -1);
if (size == 0) {
if (mKeyIsHash) {
LOG(("CacheFileMetadata::ReadMetadata() - Filesize == 0, cannot create "
"empty metadata since key is a hash. [this=%p]", this));
CacheFileIOManager::DoomFile(mHandle, nullptr);
return NS_ERROR_NOT_AVAILABLE;
}
// this is a new entry
LOG(("CacheFileMetadata::ReadMetadata() - Filesize == 0, creating empty "
"metadata. [this=%p]", this));
@ -170,6 +187,15 @@ CacheFileMetadata::ReadMetadata(CacheFileMetadataListener *aListener)
}
if (size < int64_t(sizeof(CacheFileMetadataHeader) + 2*sizeof(uint32_t))) {
if (mKeyIsHash) {
LOG(("CacheFileMetadata::ReadMetadata() - File is corrupted, cannot "
"create empty metadata since key is a hash. [this=%p, "
"filesize=%lld]", this, size));
CacheFileIOManager::DoomFile(mHandle, nullptr);
return NS_ERROR_FILE_CORRUPTED;
}
// there must be at least checksum, header and offset
LOG(("CacheFileMetadata::ReadMetadata() - File is corrupted, creating "
"empty metadata. [this=%p, filesize=%lld]", this, size));
@ -196,6 +222,15 @@ CacheFileMetadata::ReadMetadata(CacheFileMetadataListener *aListener)
mListener = aListener;
rv = CacheFileIOManager::Read(mHandle, offset, mBuf, mBufSize, this);
if (NS_FAILED(rv)) {
if (mKeyIsHash) {
LOG(("CacheFileMetadata::ReadMetadata() - CacheFileIOManager::Read() "
"failed synchronously, cannot create empty metadata since key is "
"a hash. [this=%p, rv=0x%08x]", this, rv));
CacheFileIOManager::DoomFile(mHandle, nullptr);
return rv;
}
LOG(("CacheFileMetadata::ReadMetadata() - CacheFileIOManager::Read() failed"
" synchronously, creating empty metadata. [this=%p, rv=0x%08x]",
this, rv));
@ -218,6 +253,7 @@ CacheFileMetadata::WriteMetadata(uint32_t aOffset,
MOZ_ASSERT(!mListener);
MOZ_ASSERT(!mWriteBuf);
MOZ_ASSERT(!mKeyIsHash);
nsresult rv;
@ -341,7 +377,9 @@ CacheFileMetadata::SyncReadMetadata(nsIFile *aFile)
return NS_ERROR_FAILURE;
}
rv = ParseMetadata(metaOffset, 0, false);
mKeyIsHash = true;
rv = ParseMetadata(metaOffset, 0);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
@ -579,11 +617,21 @@ CacheFileMetadata::OnDataRead(CacheFileHandle *aHandle, char *aBuf,
nsCOMPtr<CacheFileMetadataListener> listener;
if (NS_FAILED(aResult)) {
LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() failed"
", creating empty metadata. [this=%p, rv=0x%08x]", this, aResult));
if (mKeyIsHash) {
LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() "
"failed, cannot create empty metadata since key is a hash. [this=%p,"
" rv=0x%08x]", this, aResult));
InitEmptyMetadata();
retval = NS_OK;
CacheFileIOManager::DoomFile(mHandle, nullptr);
retval = aResult;
}
else {
LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() failed"
", creating empty metadata. [this=%p, rv=0x%08x]", this, aResult));
InitEmptyMetadata();
retval = NS_OK;
}
mListener.swap(listener);
listener->OnMetadataRead(retval);
@ -598,12 +646,22 @@ CacheFileMetadata::OnDataRead(CacheFileHandle *aHandle, char *aBuf,
MOZ_ASSERT(size != -1);
if (realOffset >= size) {
LOG(("CacheFileMetadata::OnDataRead() - Invalid realOffset, creating "
"empty metadata. [this=%p, realOffset=%d, size=%lld]", this,
realOffset, size));
if (mKeyIsHash) {
LOG(("CacheFileMetadata::OnDataRead() - Invalid realOffset, cannot create"
"empty metadata since key is a hash. [this=%p, realOffset=%d, "
"size=%lld]", this, realOffset, size));
InitEmptyMetadata();
retval = NS_OK;
CacheFileIOManager::DoomFile(mHandle, nullptr);
retval = NS_ERROR_FILE_CORRUPTED;
}
else {
LOG(("CacheFileMetadata::OnDataRead() - Invalid realOffset, creating "
"empty metadata. [this=%p, realOffset=%d, size=%lld]", this,
realOffset, size));
InitEmptyMetadata();
retval = NS_OK;
}
mListener.swap(listener);
listener->OnMetadataRead(retval);
@ -626,12 +684,22 @@ CacheFileMetadata::OnDataRead(CacheFileHandle *aHandle, char *aBuf,
rv = CacheFileIOManager::Read(mHandle, realOffset, mBuf, missing, this);
if (NS_FAILED(rv)) {
LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() "
"failed synchronously, creating empty metadata. [this=%p, "
"rv=0x%08x]", this, rv));
if (mKeyIsHash) {
LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() "
"failed synchronously, cannot create empty metadata since key is "
"a hash. [this=%p, rv=0x%08x]", this, rv));
InitEmptyMetadata();
retval = NS_OK;
CacheFileIOManager::DoomFile(mHandle, nullptr);
retval = rv;
}
else {
LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() "
"failed synchronously, creating empty metadata. [this=%p, "
"rv=0x%08x]", this, rv));
InitEmptyMetadata();
retval = NS_OK;
}
mListener.swap(listener);
listener->OnMetadataRead(retval);
@ -643,12 +711,21 @@ CacheFileMetadata::OnDataRead(CacheFileHandle *aHandle, char *aBuf,
// We have all data according to offset information at the end of the entry.
// Try to parse it.
rv = ParseMetadata(realOffset, realOffset - usedOffset, true);
rv = ParseMetadata(realOffset, realOffset - usedOffset);
if (NS_FAILED(rv)) {
LOG(("CacheFileMetadata::OnDataRead() - Error parsing metadata, creating "
"empty metadata. [this=%p]", this));
InitEmptyMetadata();
retval = NS_OK;
if (mKeyIsHash) {
LOG(("CacheFileMetadata::OnDataRead() - Error parsing metadata, cannot "
"create empty metadata since key is a hash. [this=%p]", this));
CacheFileIOManager::DoomFile(mHandle, nullptr);
retval = rv;
}
else {
LOG(("CacheFileMetadata::OnDataRead() - Error parsing metadata, creating "
"empty metadata. [this=%p]", this));
InitEmptyMetadata();
retval = NS_OK;
}
}
else {
retval = NS_OK;
@ -698,11 +775,10 @@ CacheFileMetadata::InitEmptyMetadata()
}
nsresult
CacheFileMetadata::ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset,
bool aHaveKey)
CacheFileMetadata::ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset)
{
LOG(("CacheFileMetadata::ParseMetadata() [this=%p, metaOffset=%d, "
"bufOffset=%d, haveKey=%u]", this, aMetaOffset, aBufOffset, aHaveKey));
"bufOffset=%d]", this, aMetaOffset, aBufOffset));
nsresult rv;
@ -742,14 +818,16 @@ CacheFileMetadata::ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset,
return NS_ERROR_FILE_CORRUPTED;
}
nsAutoCString origKey;
uint32_t keySize = reinterpret_cast<CacheFileMetadataHeader *>(
mBuf + hdrOffset)->mKeySize;
if (!aHaveKey) {
// get the key form metadata
mKey.Assign(mBuf + keyOffset, keySize);
if (mKeyIsHash) {
// get the original key
origKey.Assign(mBuf + keyOffset, keySize);
rv = ParseKey(mKey);
rv = ParseKey(origKey);
if (NS_FAILED(rv))
return rv;
}
@ -799,6 +877,11 @@ CacheFileMetadata::ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset,
memmove(mBuf, mBuf + elementsOffset, mElementsSize);
mOffset = aMetaOffset;
if (mKeyIsHash) {
mKey = origKey;
mKeyIsHash = false;
}
// TODO: shrink memory if buffer is too big
DoMemoryReport(MemoryUsage());
@ -848,15 +931,51 @@ CacheFileMetadata::EnsureBuffer(uint32_t aSize)
nsresult
CacheFileMetadata::ParseKey(const nsACString &aKey)
{
nsresult rv;
if (aKey.Length() < 4) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsILoadContextInfo> info;
rv = CacheFileUtils::ParseKey(aKey, getter_AddRefs(info), nullptr);
NS_ENSURE_SUCCESS(rv, rv);
if (aKey[1] == '-') {
mAnonymous = false;
}
else if (aKey[1] == 'A') {
mAnonymous = true;
}
else {
return NS_ERROR_FAILURE;
}
mAnonymous = info->IsAnonymous();
mAppId = info->AppId();
mInBrowser = info->IsInBrowserElement();
if (aKey[2] != ':') {
return NS_ERROR_FAILURE;
}
int32_t appIdEndIdx = aKey.FindChar(':', 3);
if (appIdEndIdx == kNotFound) {
return NS_ERROR_FAILURE;
}
if (aKey[appIdEndIdx - 1] == 'B') {
mInBrowser = true;
appIdEndIdx--;
} else {
mInBrowser = false;
}
if (appIdEndIdx < 3) {
return NS_ERROR_FAILURE;
}
if (appIdEndIdx == 3) {
mAppId = nsILoadContextInfo::NO_APP_ID;
}
else {
nsAutoCString appIdStr(Substring(aKey, 3, appIdEndIdx - 3));
nsresult rv;
int64_t appId64 = appIdStr.ToInteger64(&rv);
if (NS_FAILED(rv) || appId64 > PR_UINT32_MAX)
return NS_ERROR_FAILURE;
mAppId = appId64;
}
return NS_OK;
}

Просмотреть файл

@ -62,13 +62,15 @@ public:
NS_DECL_THREADSAFE_ISUPPORTS
CacheFileMetadata(CacheFileHandle *aHandle,
const nsACString &aKey);
const nsACString &aKey,
bool aKeyIsHash);
CacheFileMetadata(const nsACString &aKey);
CacheFileMetadata();
void SetHandle(CacheFileHandle *aHandle);
nsresult GetKey(nsACString &_retval);
bool KeyIsHash();
nsresult ReadMetadata(CacheFileMetadataListener *aListener);
nsresult WriteMetadata(uint32_t aOffset,
@ -112,13 +114,14 @@ private:
virtual ~CacheFileMetadata();
void InitEmptyMetadata();
nsresult ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset, bool aHaveKey);
nsresult ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset);
nsresult CheckElements(const char *aBuf, uint32_t aSize);
void EnsureBuffer(uint32_t aSize);
nsresult ParseKey(const nsACString &aKey);
nsRefPtr<CacheFileHandle> mHandle;
nsCString mKey;
bool mKeyIsHash;
CacheHash::Hash16_t *mHashArray;
uint32_t mHashArraySize;
uint32_t mHashCount;

Просмотреть файл

@ -1,115 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CacheLog.h"
#include "CacheFileUtils.h"
#include "LoadContextInfo.h"
#include "nsCOMPtr.h"
#include "nsString.h"
namespace mozilla {
namespace net {
namespace CacheFileUtils {
nsresult ParseKey(const nsACString &aKey,
nsILoadContextInfo **aInfo,
nsACString *aURL)
{
bool isPrivate;
bool isAnonymous;
bool isInBrowser;
uint32_t appId;
if (aKey.Length() < 4) {
return NS_ERROR_FAILURE;
}
if (aKey[0] == '-') {
isPrivate = false;
}
else if (aKey[0] == 'P') {
isPrivate = true;
}
else {
return NS_ERROR_FAILURE;
}
if (aKey[1] == '-') {
isAnonymous = false;
}
else if (aKey[1] == 'A') {
isAnonymous = true;
}
else {
return NS_ERROR_FAILURE;
}
if (aKey[2] != ':') {
return NS_ERROR_FAILURE;
}
int32_t appIdEndIdx = aKey.FindChar(':', 3);
if (appIdEndIdx == kNotFound) {
return NS_ERROR_FAILURE;
}
if (aKey[appIdEndIdx - 1] == 'B') {
isInBrowser = true;
appIdEndIdx--;
} else {
isInBrowser = false;
}
if (appIdEndIdx < 3) {
return NS_ERROR_FAILURE;
}
if (appIdEndIdx == 3) {
appId = nsILoadContextInfo::NO_APP_ID;
}
else {
nsAutoCString appIdStr(Substring(aKey, 3, appIdEndIdx - 3));
nsresult rv;
int64_t appId64 = appIdStr.ToInteger64(&rv);
if (NS_FAILED(rv) || appId64 > PR_UINT32_MAX)
return NS_ERROR_FAILURE;
appId = appId64;
}
if (aInfo) {
nsCOMPtr<nsILoadContextInfo> info;
info = GetLoadContextInfo(isPrivate, appId, isInBrowser, isAnonymous);
info.forget(aInfo);
}
if (aURL) {
*aURL = Substring(aKey, appIdEndIdx + 1);
}
return NS_OK;
}
void CreateKeyPrefix(nsILoadContextInfo* aInfo, nsACString &_retval)
{
/**
* This key is used to salt file hashes. When form of the key is changed
* cache entries will fail to find on disk.
*/
_retval.Assign(aInfo->IsPrivate() ? 'P' : '-');
_retval.Append(aInfo->IsAnonymous() ? 'A' : '-');
_retval.Append(':');
if (aInfo->AppId() != nsILoadContextInfo::NO_APP_ID) {
_retval.AppendInt(aInfo->AppId());
}
if (aInfo->IsInBrowserElement()) {
_retval.Append('B');
}
}
} // CacheFileUtils
} // net
} // mozilla

Просмотреть файл

@ -1,27 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef CacheFileUtils__h__
#define CacheFileUtils__h__
#include "nsError.h"
class nsILoadContextInfo;
class nsACString;
namespace mozilla {
namespace net {
namespace CacheFileUtils {
nsresult ParseKey(const nsACString &aKey,
nsILoadContextInfo **aInfo,
nsACString *aURL);
void CreateKeyPrefix(nsILoadContextInfo* aInfo, nsACString &_retval);
} // CacheFileUtils
} // net
} // mozilla
#endif

Просмотреть файл

@ -34,8 +34,8 @@ public:
WRITE,
MANAGEMENT,
CLOSE,
BUILD_OR_UPDATE_INDEX,
EVICT,
BUILD_OR_UPDATE_INDEX,
LAST_LEVEL
};

Просмотреть файл

@ -49,8 +49,6 @@ public:
, mDoNotSearchInIndex(false)
, mDoNotSearchInUpdates(false)
{
mIndex->AssertOwnsLock();
mHash = aHash;
CacheIndexEntry *entry = FindEntry();
mIndex->mIndexStats.BeforeChange(entry);
@ -63,8 +61,6 @@ public:
~CacheIndexEntryAutoManage()
{
mIndex->AssertOwnsLock();
CacheIndexEntry *entry = FindEntry();
mIndex->mIndexStats.AfterChange(entry);
if (!entry || !entry->IsInitialized() || entry->IsRemoved()) {
@ -85,19 +81,11 @@ public:
// record has a different address, we have to replace it
replaceFrecency = replaceExpiration = true;
} else {
if (entry->mRec->mFrecency == 0 &&
entry->mRec->mExpirationTime == nsICacheEntry::NO_EXPIRATION_TIME) {
// This is a special case when we want to make sure that the entry is
// placed at the end of the lists even when the values didn't change.
replaceFrecency = replaceExpiration = true;
if (entry->mRec->mFrecency != mOldFrecency) {
replaceFrecency = true;
}
else {
if (entry->mRec->mFrecency != mOldFrecency) {
replaceFrecency = true;
}
if (entry->mRec->mExpirationTime != mOldExpirationTime) {
replaceExpiration = true;
}
if (entry->mRec->mExpirationTime != mOldExpirationTime) {
replaceExpiration = true;
}
}
@ -1043,74 +1031,6 @@ CacheIndex::HasEntry(const nsACString &aKey, EntryStatus *_retval)
return NS_OK;
}
// static
nsresult
CacheIndex::GetEntryForEviction(SHA1Sum::Hash *aHash, uint32_t *aCnt)
{
LOG(("CacheIndex::GetEntryForEviction()"));
nsRefPtr<CacheIndex> index = gInstance;
if (!index)
return NS_ERROR_NOT_INITIALIZED;
CacheIndexAutoLock lock(index);
if (!index->IsIndexUsable()) {
return NS_ERROR_NOT_AVAILABLE;
}
MOZ_ASSERT(index->mFrecencyArray.Length() ==
index->mExpirationArray.Length());
if (index->mExpirationArray.Length() == 0)
return NS_ERROR_NOT_AVAILABLE;
uint32_t now = PR_Now() / PR_USEC_PER_SEC;
if (index->mExpirationArray[0]->mExpirationTime < now) {
memcpy(aHash, &index->mExpirationArray[0]->mHash, sizeof(SHA1Sum::Hash));
*aCnt = index->mExpirationArray.Length();
LOG(("CacheIndex::GetEntryForEviction() - returning entry from expiration "
"array [hash=%08x%08x%08x%08x%08x, cnt=%u, expTime=%u, now=%u, "
"frecency=%u]", LOGSHA1(aHash), *aCnt,
index->mExpirationArray[0]->mExpirationTime, now,
index->mExpirationArray[0]->mFrecency));
}
else {
memcpy(aHash, &index->mFrecencyArray[0]->mHash, sizeof(SHA1Sum::Hash));
*aCnt = index->mFrecencyArray.Length();
LOG(("CacheIndex::GetEntryForEviction() - returning entry from frecency "
"array [hash=%08x%08x%08x%08x%08x, cnt=%u, expTime=%u, now=%u, "
"frecency=%u]", LOGSHA1(aHash), *aCnt,
index->mExpirationArray[0]->mExpirationTime, now,
index->mExpirationArray[0]->mFrecency));
}
return NS_OK;
}
// static
nsresult
CacheIndex::GetCacheSize(uint32_t *_retval)
{
LOG(("CacheIndex::GetCacheSize()"));
nsRefPtr<CacheIndex> index = gInstance;
if (!index)
return NS_ERROR_NOT_INITIALIZED;
CacheIndexAutoLock lock(index);
if (!index->IsIndexUsable()) {
return NS_ERROR_NOT_AVAILABLE;
}
*_retval = index->mIndexStats.Size();
LOG(("CacheIndex::GetCacheSize() - returning %u", *_retval));
return NS_OK;
}
bool
CacheIndex::IsIndexUsable()
{
@ -2882,13 +2802,6 @@ CacheIndex::ChangeState(EState aNewState)
return;
}
// Try to evict entries over limit everytime we're leaving state READING,
// BUILDING or UPDATING, but not during shutdown.
if (!mShuttingDown && aNewState != SHUTDOWN &&
(mState == READING || mState == BUILDING || mState == UPDATING)) {
CacheFileIOManager::EvictIfOverLimit();
}
mState = aNewState;
}
@ -2935,13 +2848,6 @@ public:
return a->mFrecency == b->mFrecency;
}
bool LessThan(CacheIndexRecord* a, CacheIndexRecord* b) const {
// Place entries with frecency 0 at the end of the array.
if (a->mFrecency == 0) {
return false;
}
if (b->mFrecency == 0) {
return true;
}
return a->mFrecency < b->mFrecency;
}
};

Просмотреть файл

@ -348,7 +348,7 @@ public:
return mCount - mRemoved - mNotInitialized - mEmpty;
}
uint32_t Size() {
int64_t Size() {
MOZ_ASSERT(!mStateLogged, "CacheIndexStats::Size() - state logged!");
return mSize;
}
@ -389,7 +389,7 @@ public:
MOZ_ASSERT(mEmpty);
mEmpty--;
} else {
MOZ_ASSERT(mSize >= aEntry->GetFileSize());
MOZ_ASSERT(mSize);
mSize -= aEntry->GetFileSize();
}
}
@ -441,7 +441,7 @@ private:
uint32_t mDirty;
uint32_t mFresh;
uint32_t mEmpty;
uint32_t mSize;
int64_t mSize;
#ifdef DEBUG
// We completely remove the data about an entry from the stats in
// BeforeChange() and set this flag to true. The entry is then modified,
@ -512,15 +512,6 @@ public:
// on any thread.
static nsresult HasEntry(const nsACString &aKey, EntryStatus *_retval);
// Returns a hash of the least important entry that should be evicted if the
// cache size is over limit and also returns a total number of all entries in
// the index.
static nsresult GetEntryForEviction(SHA1Sum::Hash *aHash, uint32_t *aCnt);
// Returns cache size in kB.
static nsresult GetCacheSize(uint32_t *_retval);
private:
friend class CacheIndexEntryAutoManage;
friend class CacheIndexAutoLock;

Просмотреть файл

@ -12,7 +12,6 @@
#include "CacheStorage.h"
#include "AppCacheStorage.h"
#include "CacheEntry.h"
#include "CacheFileUtils.h"
#include "OldWrappers.h"
#include "nsCacheService.h"
@ -34,6 +33,23 @@ namespace net {
namespace {
void LoadContextInfoMappingKey(nsAutoCString &key, nsILoadContextInfo* aInfo)
{
/**
* This key is used to salt file hashes. When form of the key is changed
* cache entries will fail to find on disk.
*/
key.Append(aInfo->IsPrivate() ? 'P' : '-');
key.Append(aInfo->IsAnonymous() ? 'A' : '-');
key.Append(':');
if (aInfo->AppId() != nsILoadContextInfo::NO_APP_ID) {
key.AppendInt(aInfo->AppId());
}
if (aInfo->IsInBrowserElement()) {
key.Append('B');
}
}
void AppendMemoryStorageID(nsAutoCString &key)
{
key.Append('M');
@ -497,6 +513,7 @@ public:
~CacheFilesDeletor();
nsresult DeleteAll();
nsresult DeleteOverLimit();
nsresult DeleteDoomed();
private:
@ -513,6 +530,7 @@ private:
uint32_t mRunning;
enum {
ALL,
OVERLIMIT,
DOOMED
} mMode;
nsresult mRv;
@ -550,6 +568,12 @@ nsresult CacheFilesDeletor::DeleteAll()
return Init(CacheFileIOManager::ENTRIES);
}
nsresult CacheFilesDeletor::DeleteOverLimit()
{
mMode = OVERLIMIT;
return Init(CacheFileIOManager::ENTRIES);
}
nsresult CacheFilesDeletor::DeleteDoomed()
{
mMode = DOOMED;
@ -638,6 +662,21 @@ nsresult CacheFilesDeletor::Execute()
TimeStamp start;
switch (mMode) {
case OVERLIMIT:
// Examine file by file and delete what is considered expired/unused.
while (mEnumerator->HasMore()) {
rv = mEnumerator->GetNextCacheFile(this);
if (NS_FAILED(rv))
return rv;
// Limit up to 5 concurrent file opens
if (mRunning >= 5)
break;
++mRunning;
}
break;
case ALL:
case DOOMED:
// Simply delete all files, don't doom then though the backend
@ -658,6 +697,13 @@ nsresult CacheFilesDeletor::Execute()
rv = file->Remove(false);
if (NS_FAILED(rv)) {
LOG((" could not remove the file, probably doomed, rv=0x%08x", rv));
#if 0
// No need to open and doom the file manually since we doom all entries
// we currently have loaded in memory.
rv = mEnumerator->GetCacheFileFromFile(file, this);
if (NS_FAILED(rv))
return rv;
#endif
}
++mRunning;
@ -698,6 +744,15 @@ void CacheFilesDeletor::OnFile(CacheFile* aFile)
#endif
switch (mMode) {
case OVERLIMIT:
if (mEnumerator->HasMore())
mEnumerator->GetNextCacheFile(this);
// NO BREAK ..so far..
// mayhemer TODO - here we should decide based on frecency and exp time
// whether to delete the file or not. Then we have to check the consumption
// as well.
case ALL:
case DOOMED:
LOG((" dooming file with key=%s", key.get()));
@ -1153,7 +1208,7 @@ CacheStorageService::AddStorageEntry(CacheStorage const* aStorage,
NS_ENSURE_ARG(aStorage);
nsAutoCString contextKey;
CacheFileUtils::CreateKeyPrefix(aStorage->LoadInfo(), contextKey);
LoadContextInfoMappingKey(contextKey, aStorage->LoadInfo());
return AddStorageEntry(contextKey, aURI, aIdExtension,
aStorage->WriteToDisk(), aCreateIfNotExist, aReplace,
@ -1198,11 +1253,6 @@ CacheStorageService::AddStorageEntry(nsCSubstring const& aContextKey,
bool entryExists = entries->Get(entryKey, getter_AddRefs(entry));
// check whether the file is already doomed
if (entryExists && entry->IsFileDoomed() && !aReplace) {
aReplace = true;
}
// Check entry that is memory-only is also in related memory-only hashtable.
// If not, it has been evicted and we will truncate it ; doom is pending for it,
// this consumer just made it sooner then the entry has actually been removed
@ -1311,7 +1361,7 @@ CacheStorageService::DoomStorageEntry(CacheStorage const* aStorage,
NS_ENSURE_ARG(aURI);
nsAutoCString contextKey;
CacheFileUtils::CreateKeyPrefix(aStorage->LoadInfo(), contextKey);
LoadContextInfoMappingKey(contextKey, aStorage->LoadInfo());
nsAutoCString entryKey;
nsresult rv = CacheEntry::HashingKey(EmptyCString(), aIdExtension, aURI, entryKey);
@ -1352,7 +1402,7 @@ CacheStorageService::DoomStorageEntry(CacheStorage const* aStorage,
if (aStorage->WriteToDisk()) {
nsAutoCString contextKey;
CacheFileUtils::CreateKeyPrefix(aStorage->LoadInfo(), contextKey);
LoadContextInfoMappingKey(contextKey, aStorage->LoadInfo());
rv = CacheEntry::HashingKey(contextKey, aIdExtension, aURI, entryKey);
NS_ENSURE_SUCCESS(rv, rv);
@ -1383,7 +1433,7 @@ CacheStorageService::DoomStorageEntries(CacheStorage const* aStorage,
NS_ENSURE_ARG(aStorage);
nsAutoCString contextKey;
CacheFileUtils::CreateKeyPrefix(aStorage->LoadInfo(), contextKey);
LoadContextInfoMappingKey(contextKey, aStorage->LoadInfo());
mozilla::MutexAutoLock lock(mLock);
@ -1436,39 +1486,12 @@ CacheStorageService::WalkStorageEntries(CacheStorage const* aStorage,
NS_ENSURE_ARG(aStorage);
nsAutoCString contextKey;
CacheFileUtils::CreateKeyPrefix(aStorage->LoadInfo(), contextKey);
LoadContextInfoMappingKey(contextKey, aStorage->LoadInfo());
nsRefPtr<WalkRunnable> event = new WalkRunnable(
contextKey, aVisitEntries, aStorage->WriteToDisk(), aVisitor);
return Dispatch(event);
}
nsresult
CacheStorageService::CacheFileDoomed(nsILoadContextInfo* aLoadContextInfo,
const nsACString & aURL)
{
nsRefPtr<CacheEntry> entry;
nsAutoCString contextKey;
CacheFileUtils::CreateKeyPrefix(aLoadContextInfo, contextKey);
{
mozilla::MutexAutoLock lock(mLock);
NS_ENSURE_FALSE(mShutdown, NS_ERROR_NOT_INITIALIZED);
CacheEntryTable* entries;
if (sGlobalEntryTables->Get(contextKey, &entries)) {
entries->Get(aURL, getter_AddRefs(entry));
}
}
if (entry && entry->IsFileDoomed()) {
entry->PurgeAndDoom();
}
return NS_OK;
}
} // net
} // mozilla

Просмотреть файл

@ -103,7 +103,6 @@ private:
private:
// Following methods are thread safe to call.
friend class CacheStorage;
friend class CacheFileIOManager;
/**
* Get, or create when not existing and demanded, an entry for the storage
@ -138,14 +137,6 @@ private:
bool aVisitEntries,
nsICacheStorageVisitor* aVisitor);
/**
* CacheFileIOManager uses this method to notify CacheStorageService that
* an active entry was removed. This method is called even if the entry
* removal was originated by CacheStorageService.
*/
nsresult CacheFileDoomed(nsILoadContextInfo* aLoadContextInfo,
const nsACString & aURL);
private:
friend class CacheMemoryConsumer;

Просмотреть файл

@ -39,7 +39,6 @@ SOURCES += [
'CacheFileIOManager.cpp',
'CacheFileMetadata.cpp',
'CacheFileOutputStream.cpp',
'CacheFileUtils.cpp',
'CacheIndex.cpp',
'CacheLog.cpp',
'CacheStorage.cpp',