Bug 1745972 - Dispatch cache wrapper deletion to caller thread to acquire lock before deletion and safety-removal from frecency array. r=kershaw,necko-reviewers,valentin

Differential Revision: https://phabricator.services.mozilla.com/D151764
This commit is contained in:
edguloien 2022-08-29 17:29:32 +00:00
Родитель 1bc3803d81
Коммит 6f463ede32
2 изменённых файлов: 40 добавлений и 1 удалений

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

@ -72,6 +72,41 @@ class FrecencyComparator {
} // namespace } // namespace
// used to dispatch a wrapper deletion the caller's thread
// cannot be used on IOThread after shutdown begins
class DeleteCacheIndexRecordWrapper : public Runnable {
CacheIndexRecordWrapper* mWrapper;
public:
explicit DeleteCacheIndexRecordWrapper(CacheIndexRecordWrapper* wrapper)
: Runnable("net::CacheIndex::DeleteCacheIndexRecordWrapper"),
mWrapper(wrapper) {}
NS_IMETHOD Run() override {
StaticMutexAutoLock lock(CacheIndex::sLock);
// if somehow the item is still in the frecency array, remove it
RefPtr<CacheIndex> index = CacheIndex::gInstance;
if (index) {
bool found = index->mFrecencyArray.RecordExistedUnlocked(mWrapper);
if (found) {
LOG(
("DeleteCacheIndexRecordWrapper::Run() - \
record wrapper found in frecency array during deletion"));
index->mFrecencyArray.RemoveRecord(mWrapper, lock);
}
}
delete mWrapper;
return NS_OK;
}
};
void CacheIndexRecordWrapper::DispatchDeleteSelfToCurrentThread() {
// Dispatch during shutdown will not trigger DeleteCacheIndexRecordWrapper
nsCOMPtr<nsIRunnable> event = new DeleteCacheIndexRecordWrapper(this);
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(event));
}
CacheIndexRecordWrapper::~CacheIndexRecordWrapper() { CacheIndexRecordWrapper::~CacheIndexRecordWrapper() {
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
CacheIndex::sLock.AssertCurrentThreadOwns(); CacheIndex::sLock.AssertCurrentThreadOwns();

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

@ -110,14 +110,17 @@ static_assert(sizeof(CacheIndexRecord::mHash) +
class CacheIndexRecordWrapper final { class CacheIndexRecordWrapper final {
public: public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheIndexRecordWrapper) NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DESTROY(
CacheIndexRecordWrapper, DispatchDeleteSelfToCurrentThread());
CacheIndexRecordWrapper() : mRec(MakeUnique<CacheIndexRecord>()) {} CacheIndexRecordWrapper() : mRec(MakeUnique<CacheIndexRecord>()) {}
CacheIndexRecord* Get() { return mRec.get(); } CacheIndexRecord* Get() { return mRec.get(); }
private: private:
~CacheIndexRecordWrapper(); ~CacheIndexRecordWrapper();
void DispatchDeleteSelfToCurrentThread();
UniquePtr<CacheIndexRecord> mRec; UniquePtr<CacheIndexRecord> mRec;
friend class DeleteCacheIndexRecordWrapper;
}; };
class CacheIndexEntry : public PLDHashEntryHdr { class CacheIndexEntry : public PLDHashEntryHdr {
@ -813,6 +816,7 @@ class CacheIndex final : public CacheFileIOListener, public nsIRunnable {
friend class FileOpenHelper; friend class FileOpenHelper;
friend class CacheIndexIterator; friend class CacheIndexIterator;
friend class CacheIndexRecordWrapper; friend class CacheIndexRecordWrapper;
friend class DeleteCacheIndexRecordWrapper;
virtual ~CacheIndex(); virtual ~CacheIndex();