зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
1bc3803d81
Коммит
6f463ede32
|
@ -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();
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче