diff options
author | Moonchild <moonchild@palemoon.org> | 2021-08-11 23:49:44 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2021-08-11 23:49:44 +0000 |
commit | 61a3331fe23dda6ec1f15ba6b79aecd3f50ecd01 (patch) | |
tree | f8246eb715ddc31c143f072e81f0f62c228052e1 /netwerk | |
parent | 4932924d67c9fa578eeab6e618fec287d943f1b1 (diff) | |
download | uxp-61a3331fe23dda6ec1f15ba6b79aecd3f50ecd01.tar.gz |
[network] Use a proof of lock everywhere in cache v2.
Diffstat (limited to 'netwerk')
-rw-r--r-- | netwerk/cache2/CacheIndex.cpp | 399 | ||||
-rw-r--r-- | netwerk/cache2/CacheIndex.h | 237 | ||||
-rw-r--r-- | netwerk/cache2/CacheIndexContextIterator.cpp | 15 | ||||
-rw-r--r-- | netwerk/cache2/CacheIndexContextIterator.h | 4 | ||||
-rw-r--r-- | netwerk/cache2/CacheIndexIterator.cpp | 27 | ||||
-rw-r--r-- | netwerk/cache2/CacheIndexIterator.h | 17 |
6 files changed, 355 insertions, 344 deletions
diff --git a/netwerk/cache2/CacheIndex.cpp b/netwerk/cache2/CacheIndex.cpp index 2c6451d72d..0c46647c63 100644 --- a/netwerk/cache2/CacheIndex.cpp +++ b/netwerk/cache2/CacheIndex.cpp @@ -41,14 +41,17 @@ namespace { class FrecencyComparator { public: - bool Equals(CacheIndexRecord* a, CacheIndexRecord* b) const { + bool Equals(const RefPtr<CacheIndexRecordWrapper>& a, + const RefPtr<CacheIndexRecordWrapper>& b) const { if (!a || !b) { return false; } - return a->mFrecency == b->mFrecency; + return a->Get()->mFrecency == b->Get()->mFrecency; } - bool LessThan(CacheIndexRecord* a, CacheIndexRecord* b) const { + + bool LessThan(const RefPtr<CacheIndexRecordWrapper>& a, + const RefPtr<CacheIndexRecordWrapper>& b) const { // Removed (=null) entries must be at the end of the array. if (!a) { return false; @@ -58,14 +61,14 @@ public: } // Place entries with frecency 0 at the end of the non-removed entries. - if (a->mFrecency == 0) { + if (a->Get()->mFrecency == 0) { return false; } - if (b->mFrecency == 0) { + if (b->Get()->mFrecency == 0) { return true; } - return a->mFrecency < b->mFrecency; + return a->Get()->mFrecency < b->Get()->mFrecency; } }; @@ -75,31 +78,28 @@ public: * This helper class is responsible for keeping CacheIndex::mIndexStats and * CacheIndex::mFrecencyArray up to date. */ -class CacheIndexEntryAutoManage +class MOZ_RAII CacheIndexEntryAutoManage { public: - CacheIndexEntryAutoManage(const SHA1Sum::Hash *aHash, CacheIndex *aIndex) + CacheIndexEntryAutoManage(const SHA1Sum::Hash *aHash, CacheIndex *aIndex, + const StaticMutexAutoLock& aProofOfLock) : mIndex(aIndex) - , mOldRecord(nullptr) , mOldFrecency(0) , mDoNotSearchInIndex(false) , mDoNotSearchInUpdates(false) + , mProofOfLock(aProofOfLock) { - CacheIndex::sLock.AssertCurrentThreadOwns(); - mHash = aHash; const CacheIndexEntry *entry = FindEntry(); mIndex->mIndexStats.BeforeChange(entry); if (entry && entry->IsInitialized() && !entry->IsRemoved()) { mOldRecord = entry->mRec; - mOldFrecency = entry->mRec->mFrecency; + mOldFrecency = entry->mRec->Get()->mFrecency; } } ~CacheIndexEntryAutoManage() { - CacheIndex::sLock.AssertCurrentThreadOwns(); - const CacheIndexEntry *entry = FindEntry(); mIndex->mIndexStats.AfterChange(entry); if (!entry || !entry->IsInitialized() || entry->IsRemoved()) { @@ -107,28 +107,28 @@ public: } if (entry && !mOldRecord) { - mIndex->mFrecencyArray.AppendRecord(entry->mRec); - mIndex->AddRecordToIterators(entry->mRec); + mIndex->mFrecencyArray.AppendRecord(entry->mRec, mProofOfLock); + mIndex->AddRecordToIterators(entry->mRec, mProofOfLock); } else if (!entry && mOldRecord) { - mIndex->mFrecencyArray.RemoveRecord(mOldRecord); - mIndex->RemoveRecordFromIterators(mOldRecord); + mIndex->mFrecencyArray.RemoveRecord(mOldRecord, mProofOfLock); + mIndex->RemoveRecordFromIterators(mOldRecord, mProofOfLock); } else if (entry && mOldRecord) { if (entry->mRec != mOldRecord) { // record has a different address, we have to replace it - mIndex->ReplaceRecordInIterators(mOldRecord, entry->mRec); + mIndex->ReplaceRecordInIterators(mOldRecord, entry->mRec, mProofOfLock); - if (entry->mRec->mFrecency == mOldFrecency) { + if (entry->mRec->Get()->mFrecency == mOldFrecency) { // If frecency hasn't changed simply replace the pointer - mIndex->mFrecencyArray.ReplaceRecord(mOldRecord, entry->mRec); + mIndex->mFrecencyArray.ReplaceRecord(mOldRecord, entry->mRec, mProofOfLock); } else { // Remove old pointer and insert the new one at the end of the array - mIndex->mFrecencyArray.RemoveRecord(mOldRecord); - mIndex->mFrecencyArray.AppendRecord(entry->mRec); + mIndex->mFrecencyArray.RemoveRecord(mOldRecord, mProofOfLock); + mIndex->mFrecencyArray.AppendRecord(entry->mRec, mProofOfLock); } - } else if (entry->mRec->mFrecency != mOldFrecency) { + } else if (entry->mRec->Get()->mFrecency != mOldFrecency) { // Move the element at the end of the array - mIndex->mFrecencyArray.RemoveRecord(entry->mRec); - mIndex->mFrecencyArray.AppendRecord(entry->mRec); + mIndex->mFrecencyArray.RemoveRecord(entry->mRec, mProofOfLock); + mIndex->mFrecencyArray.AppendRecord(entry->mRec, mProofOfLock); } } else { // both entries were removed or not initialized, do nothing @@ -169,12 +169,13 @@ private: return entry; } - const SHA1Sum::Hash *mHash; + const SHA1Sum::Hash* mHash; RefPtr<CacheIndex> mIndex; - CacheIndexRecord *mOldRecord; - uint32_t mOldFrecency; - bool mDoNotSearchInIndex; - bool mDoNotSearchInUpdates; + RefPtr<CacheIndexRecordWrapper> mOldRecord; + uint32_t mOldFrecency; + bool mDoNotSearchInIndex; + bool mDoNotSearchInUpdates; + const StaticMutexAutoLock& mProofOfLock; }; class FileOpenHelper : public CacheFileIOListener @@ -236,7 +237,7 @@ NS_IMETHODIMP FileOpenHelper::OnFileOpened(CacheFileHandle *aHandle, return NS_OK; } - mIndex->OnFileOpenedInternal(this, aHandle, aResult); + mIndex->OnFileOpenedInternal(this, aHandle, aResult, lock); return NS_OK; } @@ -306,7 +307,7 @@ CacheIndex::Init(nsIFile *aCacheDirectory) RefPtr<CacheIndex> idx = new CacheIndex(); - nsresult rv = idx->InitInternal(aCacheDirectory); + nsresult rv = idx->InitInternal(aCacheDirectory, lock); NS_ENSURE_SUCCESS(rv, rv); gInstance = idx.forget(); @@ -314,7 +315,8 @@ CacheIndex::Init(nsIFile *aCacheDirectory) } nsresult -CacheIndex::InitInternal(nsIFile *aCacheDirectory) +CacheIndex::InitInternal(nsIFile *aCacheDirectory, + const StaticMutexAutoLock& aProofOfLock) { nsresult rv; @@ -323,7 +325,7 @@ CacheIndex::InitInternal(nsIFile *aCacheDirectory) mStartTime = TimeStamp::NowLoRes(); - ReadIndexFromDisk(); + ReadIndexFromDisk(aProofOfLock); return NS_OK; } @@ -402,17 +404,17 @@ CacheIndex::PreShutdownInternal() switch (mState) { case WRITING: - FinishWrite(false); + FinishWrite(false, lock); break; case READY: // nothing to do, write the journal in Shutdown() break; case READING: - FinishRead(false); + FinishRead(false, lock); break; case BUILDING: case UPDATING: - FinishUpdate(false); + FinishUpdate(false, lock); break; default: MOZ_ASSERT(false, "Implement me!"); @@ -447,7 +449,7 @@ CacheIndex::Shutdown() MOZ_ASSERT(index->mShuttingDown); EState oldState = index->mState; - index->ChangeState(SHUTDOWN); + index->ChangeState(SHUTDOWN, lock); if (oldState != READY) { LOG(("CacheIndex::Shutdown() - Unexpected state. Did posting of " @@ -456,7 +458,7 @@ CacheIndex::Shutdown() switch (oldState) { case WRITING: - index->FinishWrite(false); + index->FinishWrite(false, lock); MOZ_FALLTHROUGH; case READY: if (index->mIndexOnDiskIsValid && !index->mDontMarkIndexClean) { @@ -468,11 +470,11 @@ CacheIndex::Shutdown() } break; case READING: - index->FinishRead(false); + index->FinishRead(false, lock); break; case BUILDING: case UPDATING: - index->FinishUpdate(false); + index->FinishUpdate(false, lock); break; default: MOZ_ASSERT(false, "Unexpected state!"); @@ -512,7 +514,7 @@ CacheIndex::AddEntry(const SHA1Sum::Hash *aHash) bool updateIfNonFreshEntriesExist = false; { - CacheIndexEntryAutoManage entryMng(aHash, index); + CacheIndexEntryAutoManage entryMng(aHash, index, lock); CacheIndexEntry *entry = index->mIndex.GetEntry(*aHash); bool entryRemoved = entry && entry->IsRemoved(); @@ -593,8 +595,8 @@ CacheIndex::AddEntry(const SHA1Sum::Hash *aHash) index->mIndexNeedsUpdate = true; } - index->StartUpdatingIndexIfNeeded(); - index->WriteIndexToDiskIfNeeded(); + index->StartUpdatingIndexIfNeeded(lock); + index->WriteIndexToDiskIfNeeded(lock); return NS_OK; } @@ -621,7 +623,7 @@ CacheIndex::EnsureEntryExists(const SHA1Sum::Hash *aHash) } { - CacheIndexEntryAutoManage entryMng(aHash, index); + CacheIndexEntryAutoManage entryMng(aHash, index, lock); CacheIndexEntry *entry = index->mIndex.GetEntry(*aHash); bool entryRemoved = entry && entry->IsRemoved(); @@ -699,8 +701,8 @@ CacheIndex::EnsureEntryExists(const SHA1Sum::Hash *aHash) } } - index->StartUpdatingIndexIfNeeded(); - index->WriteIndexToDiskIfNeeded(); + index->StartUpdatingIndexIfNeeded(lock); + index->WriteIndexToDiskIfNeeded(lock); return NS_OK; } @@ -731,7 +733,7 @@ CacheIndex::InitEntry(const SHA1Sum::Hash *aHash, } { - CacheIndexEntryAutoManage entryMng(aHash, index); + CacheIndexEntryAutoManage entryMng(aHash, index, lock); CacheIndexEntry *entry = index->mIndex.GetEntry(*aHash); CacheIndexEntryUpdate *updated = nullptr; @@ -812,8 +814,8 @@ CacheIndex::InitEntry(const SHA1Sum::Hash *aHash, } } - index->StartUpdatingIndexIfNeeded(); - index->WriteIndexToDiskIfNeeded(); + index->StartUpdatingIndexIfNeeded(lock); + index->WriteIndexToDiskIfNeeded(lock); return NS_OK; } @@ -840,7 +842,7 @@ CacheIndex::RemoveEntry(const SHA1Sum::Hash *aHash) } { - CacheIndexEntryAutoManage entryMng(aHash, index); + CacheIndexEntryAutoManage entryMng(aHash, index, lock); CacheIndexEntry *entry = index->mIndex.GetEntry(*aHash); bool entryRemoved = entry && entry->IsRemoved(); @@ -907,8 +909,8 @@ CacheIndex::RemoveEntry(const SHA1Sum::Hash *aHash) } } - index->StartUpdatingIndexIfNeeded(); - index->WriteIndexToDiskIfNeeded(); + index->StartUpdatingIndexIfNeeded(lock); + index->WriteIndexToDiskIfNeeded(lock); return NS_OK; } @@ -941,7 +943,7 @@ CacheIndex::UpdateEntry(const SHA1Sum::Hash *aHash, } { - CacheIndexEntryAutoManage entryMng(aHash, index); + CacheIndexEntryAutoManage entryMng(aHash, index, lock); CacheIndexEntry *entry = index->mIndex.GetEntry(*aHash); @@ -1012,7 +1014,7 @@ CacheIndex::UpdateEntry(const SHA1Sum::Hash *aHash, } } - index->WriteIndexToDiskIfNeeded(); + index->WriteIndexToDiskIfNeeded(lock); return NS_OK; } @@ -1061,17 +1063,17 @@ CacheIndex::RemoveAll() switch (index->mState) { case WRITING: - index->FinishWrite(false); + index->FinishWrite(false, lock); break; case READY: // nothing to do break; case READING: - index->FinishRead(false); + index->FinishRead(false, lock); break; case BUILDING: case UPDATING: - index->FinishUpdate(false); + index->FinishUpdate(false, lock); break; default: MOZ_ASSERT(false, "Unexpected state!"); @@ -1088,7 +1090,7 @@ CacheIndex::RemoveAll() index->mIndexNeedsUpdate = false; index->mIndexStats.Clear(); - index->mFrecencyArray.Clear(); + index->mFrecencyArray.Clear(lock); index->mIndex.Clear(); for (uint32_t i = 0; i < index->mIterators.Length(); ) { @@ -1213,10 +1215,10 @@ CacheIndex::GetEntryForEviction(bool aIgnoreEmptyEntries, SHA1Sum::Hash *aHash, uint32_t skipped = 0; // find first non-forced valid and unpinned entry with the lowest frecency - index->mFrecencyArray.SortIfNeeded(); + index->mFrecencyArray.SortIfNeeded(lock); for (auto iter = index->mFrecencyArray.Iter(); !iter.Done(); iter.Next()) { - CacheIndexRecord *rec = iter.Get(); + CacheIndexRecord *rec = iter.Get()->Get(); memcpy(&hash, rec->mHash, sizeof(SHA1Sum::Hash)); @@ -1318,11 +1320,10 @@ CacheIndex::GetCacheStats(nsILoadContextInfo *aInfo, uint32_t *aSize, uint32_t * *aCount = 0; for (auto iter = index->mFrecencyArray.Iter(); !iter.Done(); iter.Next()) { - CacheIndexRecord *record = iter.Get(); - if (!CacheIndexEntry::RecordMatchesLoadContextInfo(record, aInfo)) + if (aInfo && !CacheIndexEntry::RecordMatchesLoadContextInfo(iter.Get(), aInfo)) continue; - *aSize += CacheIndexEntry::GetFileSize(record); + *aSize += CacheIndexEntry::GetFileSize(iter.Get()->Get()); ++*aCount; } @@ -1374,7 +1375,7 @@ CacheIndex::AsyncGetDiskConsumption(nsICacheStorageConsumptionObserver* aObserve RefPtr<CacheIndex> index = gInstance; if (index && index->mUpdateTimer) { index->mUpdateTimer->Cancel(); - index->DelayedUpdateLocked(); + index->DelayedUpdateLocked(lock); } }), CacheIOThread::INDEX); } @@ -1408,10 +1409,10 @@ CacheIndex::GetIterator(nsILoadContextInfo *aInfo, bool aAddNew, idxIter = new CacheIndexIterator(index, aAddNew); } - index->mFrecencyArray.SortIfNeeded(); + index->mFrecencyArray.SortIfNeeded(lock); for (auto iter = index->mFrecencyArray.Iter(); !iter.Done(); iter.Next()) { - idxIter->AddRecord(iter.Get()); + idxIter->AddRecord(iter.Get(), lock); } index->mIterators.AppendElement(idxIter); @@ -1512,12 +1513,10 @@ CacheIndex::HasEntryChanged(CacheIndexEntry *aEntry, } void -CacheIndex::ProcessPendingOperations() +CacheIndex::ProcessPendingOperations(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::ProcessPendingOperations()")); - sLock.AssertCurrentThreadOwns(); - for (auto iter = mPendingUpdates.Iter(); !iter.Done(); iter.Next()) { CacheIndexEntryUpdate* update = iter.Get(); @@ -1529,7 +1528,7 @@ CacheIndex::ProcessPendingOperations() CacheIndexEntry* entry = mIndex.GetEntry(*update->Hash()); { - CacheIndexEntryAutoManage emng(update->Hash(), this); + CacheIndexEntryAutoManage emng(update->Hash(), this, aProofOfLock); emng.DoNotSearchInUpdates(); if (update->IsRemoved()) { @@ -1571,7 +1570,7 @@ CacheIndex::ProcessPendingOperations() } bool -CacheIndex::WriteIndexToDiskIfNeeded() +CacheIndex::WriteIndexToDiskIfNeeded(const StaticMutexAutoLock& aProofOfLock) { if (mState != READY || mShuttingDown || mRWPending) { return false; @@ -1587,25 +1586,24 @@ CacheIndex::WriteIndexToDiskIfNeeded() return false; } - WriteIndexToDisk(); + WriteIndexToDisk(aProofOfLock); return true; } void -CacheIndex::WriteIndexToDisk() +CacheIndex::WriteIndexToDisk(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::WriteIndexToDisk()")); mIndexStats.Log(); nsresult rv; - sLock.AssertCurrentThreadOwns(); MOZ_ASSERT(mState == READY); MOZ_ASSERT(!mRWBuf); MOZ_ASSERT(!mRWHash); MOZ_ASSERT(!mRWPending); - ChangeState(WRITING); + ChangeState(WRITING, aProofOfLock); mProcessEntries = mIndexStats.ActiveEntriesCount(); @@ -1616,7 +1614,7 @@ CacheIndex::WriteIndexToDisk() mIndexFileOpener); if (NS_FAILED(rv)) { LOG(("CacheIndex::WriteIndexToDisk() - Can't open file [rv=0x%08x]", rv)); - FinishWrite(false); + FinishWrite(false, aProofOfLock); return; } @@ -1641,13 +1639,12 @@ CacheIndex::WriteIndexToDisk() } void -CacheIndex::WriteRecords() +CacheIndex::WriteRecords(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::WriteRecords()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); MOZ_ASSERT(mState == WRITING); MOZ_ASSERT(!mRWPending); @@ -1725,7 +1722,7 @@ CacheIndex::WriteRecords() if (NS_FAILED(rv)) { LOG(("CacheIndex::WriteRecords() - CacheFileIOManager::Write() failed " "synchronously [rv=0x%08x]", rv)); - FinishWrite(false); + FinishWrite(false, aProofOfLock); } else { mRWPending = true; } @@ -1734,14 +1731,12 @@ CacheIndex::WriteRecords() } void -CacheIndex::FinishWrite(bool aSucceeded) +CacheIndex::FinishWrite(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FinishWrite() [succeeded=%d]", aSucceeded)); MOZ_ASSERT((!aSucceeded && mState == SHUTDOWN) || mState == WRITING); - sLock.AssertCurrentThreadOwns(); - // If there is write operation pending we must be cancelling writing of the // index when shutting down or removing the whole index. MOZ_ASSERT(!mRWPending || (!aSucceeded && (mShuttingDown || mRemovingAll))); @@ -1759,7 +1754,7 @@ CacheIndex::FinishWrite(bool aSucceeded) bool remove = false; { - CacheIndexEntryAutoManage emng(entry->Hash(), this); + CacheIndexEntryAutoManage emng(entry->Hash(), this, aProofOfLock); if (entry->IsRemoved()) { emng.DoNotSearchInIndex(); @@ -1784,11 +1779,11 @@ CacheIndex::FinishWrite(bool aSucceeded) } } - ProcessPendingOperations(); + ProcessPendingOperations(aProofOfLock); mIndexStats.Log(); if (mState == WRITING) { - ChangeState(READY); + ChangeState(READY, aProofOfLock); mLastDumpTime = TimeStamp::NowLoRes(); } } @@ -2011,16 +2006,15 @@ CacheIndex::WriteLogToDisk() } void -CacheIndex::ReadIndexFromDisk() +CacheIndex::ReadIndexFromDisk(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::ReadIndexFromDisk()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); MOZ_ASSERT(mState == INITIAL); - ChangeState(READING); + ChangeState(READING, aProofOfLock); mIndexFileOpener = new FileOpenHelper(this); rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(INDEX_NAME), @@ -2030,7 +2024,7 @@ CacheIndex::ReadIndexFromDisk() if (NS_FAILED(rv)) { LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() " "failed [rv=0x%08x, file=%s]", rv, INDEX_NAME)); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } @@ -2042,7 +2036,7 @@ CacheIndex::ReadIndexFromDisk() if (NS_FAILED(rv)) { LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() " "failed [rv=0x%08x, file=%s]", rv, JOURNAL_NAME)); - FinishRead(false); + FinishRead(false, aProofOfLock); } mTmpFileOpener = new FileOpenHelper(this); @@ -2053,19 +2047,17 @@ CacheIndex::ReadIndexFromDisk() if (NS_FAILED(rv)) { LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() " "failed [rv=0x%08x, file=%s]", rv, TEMP_INDEX_NAME)); - FinishRead(false); + FinishRead(false, aProofOfLock); } } void -CacheIndex::StartReadingIndex() +CacheIndex::StartReadingIndex(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::StartReadingIndex()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(mIndexHandle); MOZ_ASSERT(mState == READING); MOZ_ASSERT(!mIndexOnDiskIsValid); @@ -2079,7 +2071,7 @@ CacheIndex::StartReadingIndex() if (entriesSize < 0 || entriesSize % sizeof(CacheIndexRecord)) { LOG(("CacheIndex::StartReadingIndex() - Index is corrupted")); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } @@ -2094,21 +2086,19 @@ CacheIndex::StartReadingIndex() if (NS_FAILED(rv)) { LOG(("CacheIndex::StartReadingIndex() - CacheFileIOManager::Read() failed " "synchronously [rv=0x%08x]", rv)); - FinishRead(false); + FinishRead(false, aProofOfLock); } else { mRWPending = true; } } void -CacheIndex::ParseRecords() +CacheIndex::ParseRecords(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::ParseRecords()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(!mRWPending); uint32_t entryCnt = (mIndexHandle->FileSize() - sizeof(CacheIndexHeader) - @@ -2117,7 +2107,7 @@ CacheIndex::ParseRecords() if (!mSkipEntries) { if (NetworkEndian::readUint32(mRWBuf + pos) != kIndexVersion) { - FinishRead(false); + FinishRead(false, aProofOfLock); return; } pos += sizeof(uint32_t); @@ -2163,11 +2153,11 @@ CacheIndex::ParseRecords() " whole index [dirty=%d, initialized=%d, fileEmpty=%d, fresh=%d, " "removed=%d]", tmpEntry.IsDirty(), tmpEntry.IsInitialized(), tmpEntry.IsFileEmpty(), tmpEntry.IsFresh(), tmpEntry.IsRemoved())); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } - CacheIndexEntryAutoManage emng(tmpEntry.Hash(), this); + CacheIndexEntryAutoManage emng(tmpEntry.Hash(), this, aProofOfLock); CacheIndexEntry *entry = mIndex.PutEntry(*tmpEntry.Hash()); *entry = tmpEntry; @@ -2194,7 +2184,7 @@ CacheIndex::ParseRecords() if (mRWHash->GetHash() != expectedHash) { LOG(("CacheIndex::ParseRecords() - Hash mismatch, [is %x, should be %x]", mRWHash->GetHash(), expectedHash)); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } @@ -2202,9 +2192,9 @@ CacheIndex::ParseRecords() mJournalReadSuccessfully = false; if (mJournalHandle) { - StartReadingJournal(); + StartReadingJournal(aProofOfLock); } else { - FinishRead(false); + FinishRead(false, aProofOfLock); } return; @@ -2221,7 +2211,7 @@ CacheIndex::ParseRecords() if (NS_FAILED(rv)) { LOG(("CacheIndex::ParseRecords() - CacheFileIOManager::Read() failed " "synchronously [rv=0x%08x]", rv)); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } else { mRWPending = true; @@ -2229,14 +2219,12 @@ CacheIndex::ParseRecords() } void -CacheIndex::StartReadingJournal() +CacheIndex::StartReadingJournal(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::StartReadingJournal()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(mJournalHandle); MOZ_ASSERT(mIndexOnDiskIsValid); MOZ_ASSERT(mTmpJournal.Count() == 0); @@ -2248,7 +2236,7 @@ CacheIndex::StartReadingJournal() if (entriesSize < 0 || entriesSize % sizeof(CacheIndexRecord)) { LOG(("CacheIndex::StartReadingJournal() - Journal is corrupted")); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } @@ -2262,21 +2250,19 @@ CacheIndex::StartReadingJournal() if (NS_FAILED(rv)) { LOG(("CacheIndex::StartReadingJournal() - CacheFileIOManager::Read() failed" " synchronously [rv=0x%08x]", rv)); - FinishRead(false); + FinishRead(false, aProofOfLock); } else { mRWPending = true; } } void -CacheIndex::ParseJournal() +CacheIndex::ParseJournal(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::ParseJournal()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(!mRWPending); uint32_t entryCnt = (mJournalHandle->FileSize() - @@ -2296,7 +2282,7 @@ CacheIndex::ParseJournal() LOG(("CacheIndex::ParseJournal() - Invalid entry found in journal, " "ignoring whole journal [dirty=%d, fresh=%d]", entry->IsDirty(), entry->IsFresh())); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } @@ -2321,12 +2307,12 @@ CacheIndex::ParseJournal() if (mRWHash->GetHash() != expectedHash) { LOG(("CacheIndex::ParseJournal() - Hash mismatch, [is %x, should be %x]", mRWHash->GetHash(), expectedHash)); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } mJournalReadSuccessfully = true; - FinishRead(true); + FinishRead(true, aProofOfLock); return; } @@ -2341,7 +2327,7 @@ CacheIndex::ParseJournal() if (NS_FAILED(rv)) { LOG(("CacheIndex::ParseJournal() - CacheFileIOManager::Read() failed " "synchronously [rv=0x%08x]", rv)); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } else { mRWPending = true; @@ -2349,12 +2335,10 @@ CacheIndex::ParseJournal() } void -CacheIndex::MergeJournal() +CacheIndex::MergeJournal(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::MergeJournal()")); - sLock.AssertCurrentThreadOwns(); - for (auto iter = mTmpJournal.Iter(); !iter.Done(); iter.Next()) { CacheIndexEntry* entry = iter.Get(); @@ -2363,7 +2347,7 @@ CacheIndex::MergeJournal() CacheIndexEntry* entry2 = mIndex.GetEntry(*entry->Hash()); { - CacheIndexEntryAutoManage emng(entry->Hash(), this); + CacheIndexEntryAutoManage emng(entry->Hash(), this, aProofOfLock); if (entry->IsRemoved()) { if (entry2) { entry2->MarkRemoved(); @@ -2414,10 +2398,9 @@ CacheIndex::EnsureCorrectStats() } void -CacheIndex::FinishRead(bool aSucceeded) +CacheIndex::FinishRead(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FinishRead() [succeeded=%d]", aSucceeded)); - sLock.AssertCurrentThreadOwns(); MOZ_ASSERT((!aSucceeded && mState == SHUTDOWN) || mState == READING); @@ -2471,27 +2454,27 @@ CacheIndex::FinishRead(bool aSucceeded) if (!mIndexOnDiskIsValid) { MOZ_ASSERT(mTmpJournal.Count() == 0); EnsureNoFreshEntry(); - ProcessPendingOperations(); + ProcessPendingOperations(aProofOfLock); // Remove all entries that we haven't seen during this session - RemoveNonFreshEntries(); - StartUpdatingIndex(true); + RemoveNonFreshEntries(aProofOfLock); + StartUpdatingIndex(true, aProofOfLock); return; } if (!mJournalReadSuccessfully) { mTmpJournal.Clear(); EnsureNoFreshEntry(); - ProcessPendingOperations(); - StartUpdatingIndex(false); + ProcessPendingOperations(aProofOfLock); + StartUpdatingIndex(false, aProofOfLock); return; } - MergeJournal(); + MergeJournal(aProofOfLock); EnsureNoFreshEntry(); - ProcessPendingOperations(); + ProcessPendingOperations(aProofOfLock); mIndexStats.Log(); - ChangeState(READY); + ChangeState(READY, aProofOfLock); mLastDumpTime = TimeStamp::NowLoRes(); // Do not dump new index immediately } @@ -2508,17 +2491,15 @@ CacheIndex::DelayedUpdate(nsITimer *aTimer, void *aClosure) return; } - index->DelayedUpdateLocked(); + index->DelayedUpdateLocked(lock); } // static void -CacheIndex::DelayedUpdateLocked() +CacheIndex::DelayedUpdateLocked(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::DelayedUpdateLocked()")); - sLock.AssertCurrentThreadOwns(); - nsresult rv; mUpdateTimer = nullptr; @@ -2549,7 +2530,7 @@ CacheIndex::DelayedUpdateLocked() mUpdateEventPending = false; NS_WARNING("CacheIndex::DelayedUpdateLocked() - Can't dispatch event"); LOG(("CacheIndex::DelayedUpdate() - Can't dispatch event" )); - FinishUpdate(false); + FinishUpdate(false, aProofOfLock); } } @@ -2655,12 +2636,10 @@ CacheIndex::IsUpdatePending() } void -CacheIndex::BuildIndex() +CacheIndex::BuildIndex(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::BuildIndex()")); - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(mPendingUpdates.Count() == 0); nsresult rv; @@ -2678,7 +2657,7 @@ CacheIndex::BuildIndex() } if (NS_FAILED(rv)) { - FinishUpdate(false); + FinishUpdate(false, aProofOfLock); return; } } @@ -2700,7 +2679,7 @@ CacheIndex::BuildIndex() return; } if (!file) { - FinishUpdate(NS_SUCCEEDED(rv)); + FinishUpdate(NS_SUCCEEDED(rv), aProofOfLock); return; } @@ -2780,7 +2759,7 @@ CacheIndex::BuildIndex() "failed, removing file. [name=%s]", leaf.get())); file->Remove(false); } else { - CacheIndexEntryAutoManage entryMng(&hash, this); + CacheIndexEntryAutoManage entryMng(&hash, this, aProofOfLock); entry = mIndex.PutEntry(hash); InitEntryFromDiskData(entry, meta, size); LOG(("CacheIndex::BuildIndex() - Added entry to index. [hash=%s]", @@ -2793,7 +2772,8 @@ CacheIndex::BuildIndex() } bool -CacheIndex::StartUpdatingIndexIfNeeded(bool aSwitchingToReadyState) +CacheIndex::StartUpdatingIndexIfNeeded(const StaticMutexAutoLock& aProofOfLock, + bool aSwitchingToReadyState) { // Start updating process when we are in or we are switching to READY state // and index needs update, but not during shutdown or when removing all @@ -2802,7 +2782,7 @@ CacheIndex::StartUpdatingIndexIfNeeded(bool aSwitchingToReadyState) !mShuttingDown && !mRemovingAll) { LOG(("CacheIndex::StartUpdatingIndexIfNeeded() - starting update process")); mIndexNeedsUpdate = false; - StartUpdatingIndex(false); + StartUpdatingIndex(false, aProofOfLock); return true; } @@ -2810,21 +2790,20 @@ CacheIndex::StartUpdatingIndexIfNeeded(bool aSwitchingToReadyState) } void -CacheIndex::StartUpdatingIndex(bool aRebuild) +CacheIndex::StartUpdatingIndex(bool aRebuild, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::StartUpdatingIndex() [rebuild=%d]", aRebuild)); - sLock.AssertCurrentThreadOwns(); - nsresult rv; mIndexStats.Log(); - ChangeState(aRebuild ? BUILDING : UPDATING); + ChangeState(aRebuild ? BUILDING : UPDATING, aProofOfLock); mDontMarkIndexClean = false; if (mShuttingDown || mRemovingAll) { - FinishUpdate(false); + FinishUpdate(false, aProofOfLock); return; } @@ -2861,17 +2840,15 @@ CacheIndex::StartUpdatingIndex(bool aRebuild) mUpdateEventPending = false; NS_WARNING("CacheIndex::StartUpdatingIndex() - Can't dispatch event"); LOG(("CacheIndex::StartUpdatingIndex() - Can't dispatch event" )); - FinishUpdate(false); + FinishUpdate(false, aProofOfLock); } } void -CacheIndex::UpdateIndex() +CacheIndex::UpdateIndex(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::UpdateIndex()")); - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(mPendingUpdates.Count() == 0); nsresult rv; @@ -2889,7 +2866,7 @@ CacheIndex::UpdateIndex() } if (NS_FAILED(rv)) { - FinishUpdate(false); + FinishUpdate(false, aProofOfLock); return; } } @@ -2912,7 +2889,7 @@ CacheIndex::UpdateIndex() return; } if (!file) { - FinishUpdate(NS_SUCCEEDED(rv)); + FinishUpdate(NS_SUCCEEDED(rv), aProofOfLock); return; } @@ -2983,7 +2960,7 @@ CacheIndex::UpdateIndex() "lastModifiedTime=%u]", leaf.get(), mIndexTimeStamp, lastModifiedTime / PR_MSEC_PER_SEC)); - CacheIndexEntryAutoManage entryMng(&hash, this); + CacheIndexEntryAutoManage entryMng(&hash, this, aProofOfLock); entry->MarkFresh(); continue; } @@ -3015,7 +2992,7 @@ CacheIndex::UpdateIndex() entry = mIndex.GetEntry(hash); MOZ_ASSERT(!entry || !entry->IsFresh()); - CacheIndexEntryAutoManage entryMng(&hash, this); + CacheIndexEntryAutoManage entryMng(&hash, this, aProofOfLock); if (NS_FAILED(rv)) { LOG(("CacheIndex::UpdateIndex() - CacheFileMetadata::SyncReadMetadata() " @@ -3039,15 +3016,13 @@ CacheIndex::UpdateIndex() } void -CacheIndex::FinishUpdate(bool aSucceeded) +CacheIndex::FinishUpdate(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FinishUpdate() [succeeded=%d]", aSucceeded)); MOZ_ASSERT(mState == UPDATING || mState == BUILDING || (!aSucceeded && mState == SHUTDOWN)); - sLock.AssertCurrentThreadOwns(); - if (mDirEnumerator) { if (NS_IsMainThread()) { LOG(("CacheIndex::FinishUpdate() - posting of PreShutdownInternal failed?" @@ -3074,19 +3049,19 @@ CacheIndex::FinishUpdate(bool aSucceeded) // If we've iterated over all entries successfully then all entries that // really exist on the disk are now marked as fresh. All non-fresh entries // don't exist anymore and must be removed from the index. - RemoveNonFreshEntries(); + RemoveNonFreshEntries(aProofOfLock); } // Make sure we won't start update. If the build or update failed, there is no // reason to believe that it will succeed next time. mIndexNeedsUpdate = false; - ChangeState(READY); + ChangeState(READY, aProofOfLock); mLastDumpTime = TimeStamp::NowLoRes(); // Do not dump new index immediately } void -CacheIndex::RemoveNonFreshEntries() +CacheIndex::RemoveNonFreshEntries(const StaticMutexAutoLock& aProofOfLock) { for (auto iter = mIndex.Iter(); !iter.Done(); iter.Next()) { CacheIndexEntry* entry = iter.Get(); @@ -3098,7 +3073,7 @@ CacheIndex::RemoveNonFreshEntries() "[hash=%08x%08x%08x%08x%08x]", LOGSHA1(entry->Hash()))); { - CacheIndexEntryAutoManage emng(entry->Hash(), this); + CacheIndexEntryAutoManage emng(entry->Hash(), this, aProofOfLock); emng.DoNotSearchInIndex(); } @@ -3125,7 +3100,7 @@ CacheIndex::StateString(EState aState) } void -CacheIndex::ChangeState(EState aNewState) +CacheIndex::ChangeState(EState aNewState, const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::ChangeState() changing state %s -> %s", StateString(mState), StateString(aNewState))); @@ -3139,7 +3114,7 @@ CacheIndex::ChangeState(EState aNewState) MOZ_ASSERT(!mShuttingDown || mState != READY || aNewState == SHUTDOWN); // Start updating process when switching to READY state if needed - if (aNewState == READY && StartUpdatingIndexIfNeeded(true)) { + if (aNewState == READY && StartUpdatingIndexIfNeeded(aProofOfLock, true)) { return; } @@ -3213,23 +3188,25 @@ CacheIndex::ReleaseBuffer() } void -CacheIndex::FrecencyArray::AppendRecord(CacheIndexRecord *aRecord) +CacheIndex::FrecencyArray::AppendRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FrecencyArray::AppendRecord() [record=%p, hash=%08x%08x%08x" - "%08x%08x]", aRecord, LOGSHA1(aRecord->mHash))); + "%08x%08x]", aRecord, LOGSHA1(aRecord->Get()->mHash))); MOZ_ASSERT(!mRecs.Contains(aRecord)); mRecs.AppendElement(aRecord); // If the new frecency is 0, the element should be at the end of the array, // i.e. this change doesn't affect order of the array - if (aRecord->mFrecency != 0) { + if (aRecord->Get()->mFrecency != 0) { ++mUnsortedElements; } } void -CacheIndex::FrecencyArray::RemoveRecord(CacheIndexRecord *aRecord) +CacheIndex::FrecencyArray::RemoveRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FrecencyArray::RemoveRecord() [record=%p]", aRecord)); @@ -3241,12 +3218,13 @@ CacheIndex::FrecencyArray::RemoveRecord(CacheIndexRecord *aRecord) // Calling SortIfNeeded ensures that we get rid of removed elements in the // array once we hit the limit. - SortIfNeeded(); + SortIfNeeded(aProofOfLock); } void -CacheIndex::FrecencyArray::ReplaceRecord(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord) +CacheIndex::FrecencyArray::ReplaceRecord(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FrecencyArray::ReplaceRecord() [oldRecord=%p, " "newRecord=%p]", aOldRecord, aNewRecord)); @@ -3258,7 +3236,7 @@ CacheIndex::FrecencyArray::ReplaceRecord(CacheIndexRecord *aOldRecord, } void -CacheIndex::FrecencyArray::SortIfNeeded() +CacheIndex::FrecencyArray::SortIfNeeded(const StaticMutexAutoLock& aProofOfLock) { const uint32_t kMaxUnsortedCount = 512; const uint32_t kMaxUnsortedPercent = 10; @@ -3290,44 +3268,41 @@ CacheIndex::FrecencyArray::SortIfNeeded() } void -CacheIndex::AddRecordToIterators(CacheIndexRecord *aRecord) +CacheIndex::AddRecordToIterators(CacheIndexRecordWrapper *aRecord, + const StaticMutexAutoLock& aProofOfLock) { - sLock.AssertCurrentThreadOwns(); - for (uint32_t i = 0; i < mIterators.Length(); ++i) { // Add a new record only when iterator is supposed to be updated. if (mIterators[i]->ShouldBeNewAdded()) { - mIterators[i]->AddRecord(aRecord); + mIterators[i]->AddRecord(aRecord, aProofOfLock); } } } void -CacheIndex::RemoveRecordFromIterators(CacheIndexRecord *aRecord) +CacheIndex::RemoveRecordFromIterators(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) { - sLock.AssertCurrentThreadOwns(); - for (uint32_t i = 0; i < mIterators.Length(); ++i) { // Remove the record from iterator always, it makes no sence to return // non-existing entries. Also the pointer to the record is no longer valid // once the entry is removed from index. - mIterators[i]->RemoveRecord(aRecord); + mIterators[i]->RemoveRecord(aRecord, aProofOfLock); } } void -CacheIndex::ReplaceRecordInIterators(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord) +CacheIndex::ReplaceRecordInIterators(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock) { - sLock.AssertCurrentThreadOwns(); - for (uint32_t i = 0; i < mIterators.Length(); ++i) { // We have to replace the record always since the pointer is no longer // valid after this point. NOTE: Replacing the record doesn't mean that // a new entry was added, it just means that the data in the entry was // changed (e.g. a file size) and we had to track this change in // mPendingUpdates since mIndex was read-only. - mIterators[i]->ReplaceRecord(aOldRecord, aNewRecord); + mIterators[i]->ReplaceRecord(aOldRecord, aNewRecord, aProofOfLock); } } @@ -3350,10 +3325,10 @@ CacheIndex::Run() switch (mState) { case BUILDING: - BuildIndex(); + BuildIndex(lock); break; case UPDATING: - UpdateIndex(); + UpdateIndex(lock); break; default: LOG(("CacheIndex::Run() - Update/Build was canceled")); @@ -3363,8 +3338,10 @@ CacheIndex::Run() } nsresult -CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, - CacheFileHandle *aHandle, nsresult aResult) +CacheIndex::OnFileOpenedInternal(FileOpenHelper* aOpener, + CacheFileHandle* aHandle, + nsresult aResult, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::OnFileOpenedInternal() [opener=%p, handle=%p, " "result=0x%08x]", aOpener, aHandle, aResult)); @@ -3373,8 +3350,6 @@ CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, nsresult rv; - sLock.AssertCurrentThreadOwns(); - MOZ_RELEASE_ASSERT(IsIndexUsable()); if (mState == READY && mShuttingDown) { @@ -3389,10 +3364,10 @@ CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, if (NS_FAILED(aResult)) { LOG(("CacheIndex::OnFileOpenedInternal() - Can't open index file for " "writing [rv=0x%08x]", aResult)); - FinishWrite(false); + FinishWrite(false, aProofOfLock); } else { mIndexHandle = aHandle; - WriteRecords(); + WriteRecords(aProofOfLock); } break; case READING: @@ -3401,14 +3376,14 @@ CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, if (NS_SUCCEEDED(aResult)) { if (aHandle->FileSize() == 0) { - FinishRead(false); + FinishRead(false, aProofOfLock); CacheFileIOManager::DoomFile(aHandle, nullptr); break; } else { mIndexHandle = aHandle; } } else { - FinishRead(false); + FinishRead(false, aProofOfLock); break; } } else if (aOpener == mJournalFileOpener) { @@ -3437,7 +3412,7 @@ CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, LOG(("CacheIndex::OnFileOpenedInternal() - Unexpected state, all " "files [%s, %s, %s] should never exist. Removing whole index.", INDEX_NAME, JOURNAL_NAME, TEMP_INDEX_NAME)); - FinishRead(false); + FinishRead(false, aProofOfLock); break; } } @@ -3450,11 +3425,11 @@ CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, if (NS_FAILED(rv)) { LOG(("CacheIndex::OnFileOpenedInternal() - CacheFileIOManager::" "RenameFile() failed synchronously [rv=0x%08x]", rv)); - FinishRead(false); + FinishRead(false, aProofOfLock); break; } } else { - StartReadingIndex(); + StartReadingIndex(aProofOfLock); } break; @@ -3498,7 +3473,7 @@ CacheIndex::OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, MOZ_ASSERT(mIndexHandle == aHandle); if (NS_FAILED(aResult)) { - FinishWrite(false); + FinishWrite(false, lock); } else { if (mSkipEntries == mProcessEntries) { rv = CacheFileIOManager::RenameFile(mIndexHandle, @@ -3507,10 +3482,10 @@ CacheIndex::OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, if (NS_FAILED(rv)) { LOG(("CacheIndex::OnDataWritten() - CacheFileIOManager::" "RenameFile() failed synchronously [rv=0x%08x]", rv)); - FinishWrite(false); + FinishWrite(false, lock); } } else { - WriteRecords(); + WriteRecords(lock); } } break; @@ -3543,12 +3518,12 @@ CacheIndex::OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) MOZ_ASSERT(mIndexHandle == aHandle || mJournalHandle == aHandle); if (NS_FAILED(aResult)) { - FinishRead(false); + FinishRead(false, lock); } else { if (!mIndexOnDiskIsValid) { - ParseRecords(); + ParseRecords(lock); } else { - ParseJournal(); + ParseJournal(lock); } } break; @@ -3604,7 +3579,7 @@ CacheIndex::OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) break; } - FinishWrite(NS_SUCCEEDED(aResult)); + FinishWrite(NS_SUCCEEDED(aResult), lock); break; case READING: // This is a result of renaming journal file to tmpfile. It is renamed @@ -3618,9 +3593,9 @@ CacheIndex::OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) } if (NS_FAILED(aResult)) { - FinishRead(false); + FinishRead(false, lock); } else { - StartReadingIndex(); + StartReadingIndex(lock); } break; default: diff --git a/netwerk/cache2/CacheIndex.h b/netwerk/cache2/CacheIndex.h index acb3bdd250..7d875da626 100644 --- a/netwerk/cache2/CacheIndex.h +++ b/netwerk/cache2/CacheIndex.h @@ -93,6 +93,19 @@ static_assert( sizeof(CacheIndexRecord::mFlags) == sizeof(CacheIndexRecord), "Unexpected sizeof(CacheIndexRecord)!"); +class CacheIndexRecordWrapper final +{ +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheIndexRecordWrapper) + + CacheIndexRecordWrapper() : mRec(MakeUnique<CacheIndexRecord>()) {} + CacheIndexRecord* Get() { return mRec.get(); } + +private: + ~CacheIndexRecordWrapper() = default; + UniquePtr<CacheIndexRecord> mRec; +}; + class CacheIndexEntry : public PLDHashEntryHdr { public: @@ -102,9 +115,9 @@ public: explicit CacheIndexEntry(KeyTypePointer aKey) { MOZ_COUNT_CTOR(CacheIndexEntry); - mRec = new CacheIndexRecord(); - LOG(("CacheIndexEntry::CacheIndexEntry() - Created record [rec=%p]", mRec.get())); - memcpy(&mRec->mHash, aKey, sizeof(SHA1Sum::Hash)); + mRec = new CacheIndexRecordWrapper(); + LOG(("CacheIndexEntry::CacheIndexEntry() - Created record [rec=%p]", mRec->Get())); + memcpy(&mRec->Get()->mHash, aKey, sizeof(SHA1Sum::Hash)); } CacheIndexEntry(const CacheIndexEntry& aOther) { @@ -114,13 +127,13 @@ public: { MOZ_COUNT_DTOR(CacheIndexEntry); LOG(("CacheIndexEntry::~CacheIndexEntry() - Deleting record [rec=%p]", - mRec.get())); + mRec->Get())); } // KeyEquals(): does this entry match this key? bool KeyEquals(KeyTypePointer aKey) const { - return memcmp(&mRec->mHash, aKey, sizeof(SHA1Sum::Hash)) == 0; + return memcmp(&mRec->Get()->mHash, aKey, sizeof(SHA1Sum::Hash)) == 0; } // KeyToPointer(): Convert KeyType to KeyTypePointer @@ -138,74 +151,74 @@ public: bool operator==(const CacheIndexEntry& aOther) const { - return KeyEquals(&aOther.mRec->mHash); + return KeyEquals(&aOther.mRec->Get()->mHash); } CacheIndexEntry& operator=(const CacheIndexEntry& aOther) { - MOZ_ASSERT(memcmp(&mRec->mHash, &aOther.mRec->mHash, + MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aOther.mRec->Get()->mHash, sizeof(SHA1Sum::Hash)) == 0); - mRec->mFrecency = aOther.mRec->mFrecency; - mRec->mExpirationTime = aOther.mRec->mExpirationTime; - mRec->mOriginAttrsHash = aOther.mRec->mOriginAttrsHash; - mRec->mFlags = aOther.mRec->mFlags; + mRec->Get()->mFrecency = aOther.mRec->Get()->mFrecency; + mRec->Get()->mExpirationTime = aOther.mRec->Get()->mExpirationTime; + mRec->Get()->mOriginAttrsHash = aOther.mRec->Get()->mOriginAttrsHash; + mRec->Get()->mFlags = aOther.mRec->Get()->mFlags; return *this; } void InitNew() { - mRec->mFrecency = 0; - mRec->mExpirationTime = nsICacheEntry::NO_EXPIRATION_TIME; - mRec->mOriginAttrsHash = 0; - mRec->mFlags = 0; + mRec->Get()->mFrecency = 0; + mRec->Get()->mExpirationTime = nsICacheEntry::NO_EXPIRATION_TIME; + mRec->Get()->mOriginAttrsHash = 0; + mRec->Get()->mFlags = 0; } void Init(OriginAttrsHash aOriginAttrsHash, bool aAnonymous, bool aPinned) { - MOZ_ASSERT(mRec->mFrecency == 0); - MOZ_ASSERT(mRec->mExpirationTime == nsICacheEntry::NO_EXPIRATION_TIME); - MOZ_ASSERT(mRec->mOriginAttrsHash == 0); + MOZ_ASSERT(mRec->Get()->mFrecency == 0); + MOZ_ASSERT(mRec->Get()->mExpirationTime == nsICacheEntry::NO_EXPIRATION_TIME); + MOZ_ASSERT(mRec->Get()->mOriginAttrsHash == 0); // When we init the entry it must be fresh and may be dirty - MOZ_ASSERT((mRec->mFlags & ~kDirtyMask) == kFreshMask); + MOZ_ASSERT((mRec->Get()->mFlags & ~kDirtyMask) == kFreshMask); - mRec->mOriginAttrsHash = aOriginAttrsHash; - mRec->mFlags |= kInitializedMask; + mRec->Get()->mOriginAttrsHash = aOriginAttrsHash; + mRec->Get()->mFlags |= kInitializedMask; if (aAnonymous) { - mRec->mFlags |= kAnonymousMask; + mRec->Get()->mFlags |= kAnonymousMask; } if (aPinned) { - mRec->mFlags |= kPinnedMask; + mRec->Get()->mFlags |= kPinnedMask; } } - const SHA1Sum::Hash * Hash() const { return &mRec->mHash; } + const SHA1Sum::Hash * Hash() const { return &mRec->Get()->mHash; } - bool IsInitialized() const { return !!(mRec->mFlags & kInitializedMask); } + bool IsInitialized() const { return !!(mRec->Get()->mFlags & kInitializedMask); } - mozilla::net::OriginAttrsHash OriginAttrsHash() const { return mRec->mOriginAttrsHash; } + mozilla::net::OriginAttrsHash OriginAttrsHash() const { return mRec->Get()->mOriginAttrsHash; } - bool Anonymous() const { return !!(mRec->mFlags & kAnonymousMask); } + bool Anonymous() const { return !!(mRec->Get()->mFlags & kAnonymousMask); } - bool IsRemoved() const { return !!(mRec->mFlags & kRemovedMask); } - void MarkRemoved() { mRec->mFlags |= kRemovedMask; } + bool IsRemoved() const { return !!(mRec->Get()->mFlags & kRemovedMask); } + void MarkRemoved() { mRec->Get()->mFlags |= kRemovedMask; } - bool IsDirty() const { return !!(mRec->mFlags & kDirtyMask); } - void MarkDirty() { mRec->mFlags |= kDirtyMask; } - void ClearDirty() { mRec->mFlags &= ~kDirtyMask; } + bool IsDirty() const { return !!(mRec->Get()->mFlags & kDirtyMask); } + void MarkDirty() { mRec->Get()->mFlags |= kDirtyMask; } + void ClearDirty() { mRec->Get()->mFlags &= ~kDirtyMask; } - bool IsFresh() const { return !!(mRec->mFlags & kFreshMask); } - void MarkFresh() { mRec->mFlags |= kFreshMask; } + bool IsFresh() const { return !!(mRec->Get()->mFlags & kFreshMask); } + void MarkFresh() { mRec->Get()->mFlags |= kFreshMask; } - bool IsPinned() const { return !!(mRec->mFlags & kPinnedMask); } + bool IsPinned() const { return !!(mRec->Get()->mFlags & kPinnedMask); } - void SetFrecency(uint32_t aFrecency) { mRec->mFrecency = aFrecency; } - uint32_t GetFrecency() const { return mRec->mFrecency; } + void SetFrecency(uint32_t aFrecency) { mRec->Get()->mFrecency = aFrecency; } + uint32_t GetFrecency() const { return mRec->Get()->mFrecency; } void SetExpirationTime(uint32_t aExpirationTime) { - mRec->mExpirationTime = aExpirationTime; + mRec->Get()->mExpirationTime = aExpirationTime; } - uint32_t GetExpirationTime() const { return mRec->mExpirationTime; } + uint32_t GetExpirationTime() const { return mRec->Get()->mExpirationTime; } // Sets filesize in kilobytes. void SetFileSize(uint32_t aFileSize) @@ -215,11 +228,11 @@ public: "truncating to %u", kFileSizeMask)); aFileSize = kFileSizeMask; } - mRec->mFlags &= ~kFileSizeMask; - mRec->mFlags |= aFileSize; + mRec->Get()->mFlags &= ~kFileSizeMask; + mRec->Get()->mFlags |= aFileSize; } // Returns filesize in kilobytes. - uint32_t GetFileSize() const { return GetFileSize(mRec); } + uint32_t GetFileSize() const { return GetFileSize(mRec->Get()); } static uint32_t GetFileSize(CacheIndexRecord *aRec) { return aRec->mFlags & kFileSizeMask; @@ -233,40 +246,48 @@ public: void WriteToBuf(void *aBuf) { uint8_t* ptr = static_cast<uint8_t*>(aBuf); - memcpy(ptr, mRec->mHash, sizeof(SHA1Sum::Hash)); ptr += sizeof(SHA1Sum::Hash); - NetworkEndian::writeUint32(ptr, mRec->mFrecency); ptr += sizeof(uint32_t); - NetworkEndian::writeUint64(ptr, mRec->mOriginAttrsHash); ptr += sizeof(uint64_t); - NetworkEndian::writeUint32(ptr, mRec->mExpirationTime); ptr += sizeof(uint32_t); + memcpy(ptr, mRec->Get()->mHash, sizeof(SHA1Sum::Hash)); + ptr += sizeof(SHA1Sum::Hash); + NetworkEndian::writeUint32(ptr, mRec->Get()->mFrecency); + ptr += sizeof(uint32_t); + NetworkEndian::writeUint64(ptr, mRec->Get()->mOriginAttrsHash); + ptr += sizeof(uint64_t); + NetworkEndian::writeUint32(ptr, mRec->Get()->mExpirationTime); + ptr += sizeof(uint32_t); // Dirty and fresh flags should never go to disk, since they make sense only // during current session. - NetworkEndian::writeUint32(ptr, mRec->mFlags & ~(kDirtyMask | kFreshMask)); + NetworkEndian::writeUint32(ptr, mRec->Get()->mFlags & ~(kDirtyMask | kFreshMask)); } void ReadFromBuf(void *aBuf) { const uint8_t* ptr = static_cast<const uint8_t*>(aBuf); - MOZ_ASSERT(memcmp(&mRec->mHash, ptr, sizeof(SHA1Sum::Hash)) == 0); ptr += sizeof(SHA1Sum::Hash); - mRec->mFrecency = NetworkEndian::readUint32(ptr); ptr += sizeof(uint32_t); - mRec->mOriginAttrsHash = NetworkEndian::readUint64(ptr); ptr += sizeof(uint64_t); - mRec->mExpirationTime = NetworkEndian::readUint32(ptr); ptr += sizeof(uint32_t); - mRec->mFlags = NetworkEndian::readUint32(ptr); + MOZ_ASSERT(memcmp(&mRec->Get()->mHash, ptr, sizeof(SHA1Sum::Hash)) == 0); + ptr += sizeof(SHA1Sum::Hash); + mRec->Get()->mFrecency = NetworkEndian::readUint32(ptr); + ptr += sizeof(uint32_t); + mRec->Get()->mOriginAttrsHash = NetworkEndian::readUint64(ptr); + ptr += sizeof(uint64_t); + mRec->Get()->mExpirationTime = NetworkEndian::readUint32(ptr); + ptr += sizeof(uint32_t); + mRec->Get()->mFlags = NetworkEndian::readUint32(ptr); } void Log() const { LOG(("CacheIndexEntry::Log() [this=%p, hash=%08x%08x%08x%08x%08x, fresh=%u," " initialized=%u, removed=%u, dirty=%u, anonymous=%u, " "originAttrsHash=%llx, frecency=%u, expirationTime=%u, size=%u]", - this, LOGSHA1(mRec->mHash), IsFresh(), IsInitialized(), IsRemoved(), - IsDirty(), Anonymous(), OriginAttrsHash(), GetFrecency(), + this, LOGSHA1(mRec->Get()->mHash), IsFresh(), IsInitialized(), + IsRemoved(), IsDirty(), Anonymous(), OriginAttrsHash(), GetFrecency(), GetExpirationTime(), GetFileSize())); } - static bool RecordMatchesLoadContextInfo(CacheIndexRecord *aRec, + static bool RecordMatchesLoadContextInfo(CacheIndexRecordWrapper *aRec, nsILoadContextInfo *aInfo) { if (!aInfo->IsPrivate() && - GetOriginAttrsHash(*aInfo->OriginAttributesPtr()) == aRec->mOriginAttrsHash && - aInfo->IsAnonymous() == !!(aRec->mFlags & kAnonymousMask)) { + GetOriginAttrsHash(*aInfo->OriginAttributesPtr()) == aRec->Get()->mOriginAttrsHash && + aInfo->IsAnonymous() == !!(aRec->Get()->mFlags & kAnonymousMask)) { return true; } @@ -276,7 +297,7 @@ public: // Memory reporting size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(mRec.get()); + return mallocSizeOf(mRec->Get()); } size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const @@ -313,7 +334,7 @@ private: // FileSize in kilobytes static const uint32_t kFileSizeMask = 0x00FFFFFF; - nsAutoPtr<CacheIndexRecord> mRec; + RefPtr<CacheIndexRecordWrapper> mRec; }; class CacheIndexEntryUpdate : public CacheIndexEntry @@ -334,7 +355,7 @@ public: CacheIndexEntryUpdate& operator=(const CacheIndexEntry& aOther) { - MOZ_ASSERT(memcmp(&mRec->mHash, &aOther.mRec->mHash, + MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aOther.mRec->Get()->mHash, sizeof(SHA1Sum::Hash)) == 0); mUpdateFlags = 0; *(static_cast<CacheIndexEntry *>(this)) = aOther; @@ -367,21 +388,21 @@ public: } void ApplyUpdate(CacheIndexEntry *aDst) { - MOZ_ASSERT(memcmp(&mRec->mHash, &aDst->mRec->mHash, + MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aDst->mRec->Get()->mHash, sizeof(SHA1Sum::Hash)) == 0); if (mUpdateFlags & kFrecencyUpdatedMask) { - aDst->mRec->mFrecency = mRec->mFrecency; + aDst->mRec->Get()->mFrecency = mRec->Get()->mFrecency; } if (mUpdateFlags & kExpirationUpdatedMask) { - aDst->mRec->mExpirationTime = mRec->mExpirationTime; + aDst->mRec->Get()->mExpirationTime = mRec->Get()->mExpirationTime; } - aDst->mRec->mOriginAttrsHash = mRec->mOriginAttrsHash; + aDst->mRec->Get()->mOriginAttrsHash = mRec->Get()->mOriginAttrsHash; if (mUpdateFlags & kFileSizeUpdatedMask) { - aDst->mRec->mFlags = mRec->mFlags; + aDst->mRec->Get()->mFlags = mRec->Get()->mFlags; } else { // Copy all flags except file size. - aDst->mRec->mFlags &= kFileSizeMask; - aDst->mRec->mFlags |= (mRec->mFlags & ~kFileSizeMask); + aDst->mRec->Get()->mFlags &= kFileSizeMask; + aDst->mRec->Get()->mFlags |= (mRec->Get()->mFlags & ~kFileSizeMask); } } @@ -698,7 +719,9 @@ private: NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult) override; nsresult OnFileOpenedInternal(FileOpenHelper *aOpener, - CacheFileHandle *aHandle, nsresult aResult); + CacheFileHandle *aHandle, + nsresult aResult, + const StaticMutexAutoLock& aProofOfLock); NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, nsresult aResult) override; NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) override; @@ -706,7 +729,7 @@ private: NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) override; NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) override; - nsresult InitInternal(nsIFile *aCacheDirectory); + nsresult InitInternal(nsIFile *aCacheDirectory, const StaticMutexAutoLock& aProofOfLock); void PreShutdownInternal(); // This method returns false when index is not initialized or is shut down. @@ -727,7 +750,7 @@ private: const uint32_t *aSize); // Merge all pending operations from mPendingUpdates into mIndex. - void ProcessPendingOperations(); + void ProcessPendingOperations(const StaticMutexAutoLock& aProofOfLock); // Following methods perform writing of the index file. // @@ -739,14 +762,14 @@ private: // // Starts writing of index when both limits (minimal delay between writes and // minimum number of changes in index) were exceeded. - bool WriteIndexToDiskIfNeeded(); + bool WriteIndexToDiskIfNeeded(const StaticMutexAutoLock& aProofOfLock); // Starts writing of index file. - void WriteIndexToDisk(); + void WriteIndexToDisk(const StaticMutexAutoLock& aProofOfLock); // Serializes part of mIndex hashtable to the write buffer a writes the buffer // to the file. - void WriteRecords(); + void WriteRecords(const StaticMutexAutoLock& aProofOfLock); // Finalizes writing process. - void FinishWrite(bool aSucceeded); + void FinishWrite(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock); // Following methods perform writing of the journal during shutdown. All these // methods must be called only during shutdown since they write/delete files @@ -799,17 +822,17 @@ private: // FF crashes during parsing of the index. // // Initiates reading index from disk. - void ReadIndexFromDisk(); + void ReadIndexFromDisk(const StaticMutexAutoLock& aProofOfLock); // Starts reading data from index file. - void StartReadingIndex(); + void StartReadingIndex(const StaticMutexAutoLock& aProofOfLock); // Parses data read from index file. - void ParseRecords(); + void ParseRecords(const StaticMutexAutoLock& aProofOfLock); // Starts reading data from journal file. - void StartReadingJournal(); + void StartReadingJournal(const StaticMutexAutoLock& aProofOfLock); // Parses data read from journal file. - void ParseJournal(); + void ParseJournal(const StaticMutexAutoLock& aProofOfLock); // Merges entries from journal into mIndex. - void MergeJournal(); + void MergeJournal(const StaticMutexAutoLock& aProofOfLock); // In debug build this method checks that we have no fresh entry in mIndex // after we finish reading index and before we process pending operations. void EnsureNoFreshEntry(); @@ -817,12 +840,12 @@ private: // to make sure mIndexStats contains correct information. void EnsureCorrectStats(); // Finalizes reading process. - void FinishRead(bool aSucceeded); + void FinishRead(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock); // Following methods perform updating and building of the index. // Timer callback that starts update or build process. static void DelayedUpdate(nsITimer *aTimer, void *aClosure); - void DelayedUpdateLocked(); + void DelayedUpdateLocked(const StaticMutexAutoLock& aProofOfLock); // Posts timer event that start update or build process. nsresult ScheduleUpdateTimer(uint32_t aDelay); nsresult SetupDirectoryEnumerator(); @@ -833,20 +856,22 @@ private: bool IsUpdatePending(); // Iterates through all files in entries directory that we didn't create/open // during this session, parses them and adds the entries to the index. - void BuildIndex(); + void BuildIndex(const StaticMutexAutoLock& aProofOfLock); - bool StartUpdatingIndexIfNeeded(bool aSwitchingToReadyState = false); + bool StartUpdatingIndexIfNeeded(const StaticMutexAutoLock& aProofOfLock, + bool aSwitchingToReadyState = false); // Starts update or build process or fires a timer when it is too early after // startup. - void StartUpdatingIndex(bool aRebuild); + void StartUpdatingIndex(bool aRebuild, + const StaticMutexAutoLock& aProofOfLock); // Iterates through all files in entries directory that we didn't create/open // during this session and theirs last modified time is newer than timestamp // in the index header. Parses the files and adds the entries to the index. - void UpdateIndex(); + void UpdateIndex(const StaticMutexAutoLock& aProofOfLock); // Finalizes update or build process. - void FinishUpdate(bool aSucceeded); + void FinishUpdate(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock); - void RemoveNonFreshEntries(); + void RemoveNonFreshEntries(const StaticMutexAutoLock& aProofOfLock); enum EState { // Initial state in which the index is not usable @@ -899,7 +924,7 @@ private: }; static char const * StateString(EState aState); - void ChangeState(EState aNewState); + void ChangeState(EState aNewState, const StaticMutexAutoLock& aProofOfLock); void NotifyAsyncGetDiskConsumptionCallbacks(); // Allocates and releases buffer used for reading and writing index. @@ -907,10 +932,13 @@ private: void ReleaseBuffer(); // Methods used by CacheIndexEntryAutoManage to keep the iterators up to date. - void AddRecordToIterators(CacheIndexRecord *aRecord); - void RemoveRecordFromIterators(CacheIndexRecord *aRecord); - void ReplaceRecordInIterators(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord); + void AddRecordToIterators(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + void RemoveRecordFromIterators(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + void ReplaceRecordInIterators(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock); // Memory reporting (private part) size_t SizeOfExcludingThisInternal(mozilla::MallocSizeOf mallocSizeOf) const; @@ -1023,7 +1051,7 @@ private: class Iterator { public: - explicit Iterator(nsTArray<CacheIndexRecord *> *aRecs) + explicit Iterator(nsTArray<RefPtr<CacheIndexRecordWrapper>>* aRecs) : mRecs(aRecs) , mIdx(0) { @@ -1034,7 +1062,7 @@ private: bool Done() const { return mIdx == mRecs->Length(); } - CacheIndexRecord* Get() const + CacheIndexRecordWrapper* Get() const { MOZ_ASSERT(!Done()); return (*mRecs)[mIdx]; @@ -1050,7 +1078,7 @@ private: } private: - nsTArray<CacheIndexRecord *> *mRecs; + nsTArray<RefPtr<CacheIndexRecordWrapper>>* mRecs; uint32_t mIdx; }; @@ -1061,19 +1089,22 @@ private: , mRemovedElements(0) {} // Methods used by CacheIndexEntryAutoManage to keep the array up to date. - void AppendRecord(CacheIndexRecord *aRecord); - void RemoveRecord(CacheIndexRecord *aRecord); - void ReplaceRecord(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord); - void SortIfNeeded(); + void AppendRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + void RemoveRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + void ReplaceRecord(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock); + void SortIfNeeded(const StaticMutexAutoLock& aProofOfLock); size_t Length() const { return mRecs.Length() - mRemovedElements; } - void Clear() { mRecs.Clear(); } + void Clear(const StaticMutexAutoLock& aProofOfLock) { mRecs.Clear(); } private: friend class CacheIndex; - nsTArray<CacheIndexRecord *> mRecs; + nsTArray<RefPtr<CacheIndexRecordWrapper>> mRecs; uint32_t mUnsortedElements; // Instead of removing elements from the array immediately, we null them out // and the iterator skips them when accessing the array. The null pointers diff --git a/netwerk/cache2/CacheIndexContextIterator.cpp b/netwerk/cache2/CacheIndexContextIterator.cpp index 5f3cb7bd7c..570df2e058 100644 --- a/netwerk/cache2/CacheIndexContextIterator.cpp +++ b/netwerk/cache2/CacheIndexContextIterator.cpp @@ -24,20 +24,11 @@ CacheIndexContextIterator::~CacheIndexContextIterator() } void -CacheIndexContextIterator::AddRecord(CacheIndexRecord *aRecord) +CacheIndexContextIterator::AddRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) { if (CacheIndexEntry::RecordMatchesLoadContextInfo(aRecord, mInfo)) { - CacheIndexIterator::AddRecord(aRecord); - } -} - -void -CacheIndexContextIterator::AddRecords( - const nsTArray<CacheIndexRecord *> &aRecords) -{ - // We need to add one by one so that those with wrong context are ignored. - for (uint32_t i = 0; i < aRecords.Length(); ++i) { - AddRecord(aRecords[i]); + CacheIndexIterator::AddRecord(aRecord, aProofOfLock); } } diff --git a/netwerk/cache2/CacheIndexContextIterator.h b/netwerk/cache2/CacheIndexContextIterator.h index 32eb9c4789..a0a595ae68 100644 --- a/netwerk/cache2/CacheIndexContextIterator.h +++ b/netwerk/cache2/CacheIndexContextIterator.h @@ -20,8 +20,8 @@ public: virtual ~CacheIndexContextIterator(); private: - virtual void AddRecord(CacheIndexRecord *aRecord); - virtual void AddRecords(const nsTArray<CacheIndexRecord *> &aRecords); + virtual void AddRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) override; nsCOMPtr<nsILoadContextInfo> mInfo; }; diff --git a/netwerk/cache2/CacheIndexIterator.cpp b/netwerk/cache2/CacheIndexIterator.cpp index 0d56ec81f5..6715b70835 100644 --- a/netwerk/cache2/CacheIndexIterator.cpp +++ b/netwerk/cache2/CacheIndexIterator.cpp @@ -24,7 +24,9 @@ CacheIndexIterator::~CacheIndexIterator() { LOG(("CacheIndexIterator::~CacheIndexIterator() [this=%p]", this)); - Close(); + StaticMutexAutoLock lock(CacheIndex::sLock); + ClearRecords(lock); + CloseInternal(NS_ERROR_NOT_AVAILABLE); } nsresult @@ -43,7 +45,7 @@ CacheIndexIterator::GetNextHash(SHA1Sum::Hash *aHash) return mStatus; } - memcpy(aHash, mRecords[mRecords.Length() - 1]->mHash, sizeof(SHA1Sum::Hash)); + memcpy(aHash, mRecords[mRecords.Length() - 1]->Get()->mHash, sizeof(SHA1Sum::Hash)); mRecords.RemoveElementAt(mRecords.Length() - 1); return NS_OK; @@ -82,8 +84,13 @@ CacheIndexIterator::CloseInternal(nsresult aStatus) return NS_OK; } -void -CacheIndexIterator::AddRecord(CacheIndexRecord *aRecord) +void CacheIndexIterator::ClearRecords(const StaticMutexAutoLock& aProofOfLock) +{ + mRecords.Clear(); +} + +void CacheIndexIterator::AddRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndexIterator::AddRecord() [this=%p, record=%p]", this, aRecord)); @@ -91,7 +98,8 @@ CacheIndexIterator::AddRecord(CacheIndexRecord *aRecord) } bool -CacheIndexIterator::RemoveRecord(CacheIndexRecord *aRecord) +CacheIndexIterator::RemoveRecord(CacheIndexRecordWrapper *aRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndexIterator::RemoveRecord() [this=%p, record=%p]", this, aRecord)); @@ -100,14 +108,15 @@ CacheIndexIterator::RemoveRecord(CacheIndexRecord *aRecord) } bool -CacheIndexIterator::ReplaceRecord(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord) +CacheIndexIterator::ReplaceRecord(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndexIterator::ReplaceRecord() [this=%p, oldRecord=%p, " "newRecord=%p]", this, aOldRecord, aNewRecord)); - if (RemoveRecord(aOldRecord)) { - AddRecord(aNewRecord); + if (RemoveRecord(aOldRecord, aProofOfLock)) { + AddRecord(aNewRecord, aProofOfLock); return true; } diff --git a/netwerk/cache2/CacheIndexIterator.h b/netwerk/cache2/CacheIndexIterator.h index 9fe96989ec..fd38fc2a03 100644 --- a/netwerk/cache2/CacheIndexIterator.h +++ b/netwerk/cache2/CacheIndexIterator.h @@ -9,12 +9,13 @@ #include "nsCOMPtr.h" #include "nsAutoPtr.h" #include "mozilla/SHA1.h" +#include "mozilla/StaticMutex.h" namespace mozilla { namespace net { class CacheIndex; -struct CacheIndexRecord; +class CacheIndexRecordWrapper; class CacheIndexIterator { @@ -42,14 +43,18 @@ protected: nsresult CloseInternal(nsresult aStatus); bool ShouldBeNewAdded() { return mAddNew; } - virtual void AddRecord(CacheIndexRecord *aRecord); - bool RemoveRecord(CacheIndexRecord *aRecord); - bool ReplaceRecord(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord); + virtual void AddRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + bool RemoveRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + bool ReplaceRecord(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock); + void ClearRecords(const StaticMutexAutoLock& aProofOfLock); nsresult mStatus; RefPtr<CacheIndex> mIndex; - nsTArray<CacheIndexRecord *> mRecords; + nsTArray<RefPtr<CacheIndexRecordWrapper>> mRecords; bool mAddNew; }; |