From c14f38846e6180af139e9a3dfb13575455d6698f Mon Sep 17 00:00:00 2001 From: "valeski%netscape.com" Date: Fri, 1 Sep 2000 19:11:24 +0000 Subject: [PATCH] 32185. r=wan-teh. Fixing hashtable enumeration lossage. git-svn-id: svn://10.0.0.236/trunk@77909 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/xpcom/ds/nsHashtable.cpp | 20 +++++++++++++++----- mozilla/xpcom/ds/nsHashtable.h | 1 + 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/mozilla/xpcom/ds/nsHashtable.cpp b/mozilla/xpcom/ds/nsHashtable.cpp index 9263eb79d1a..2275b92a86f 100644 --- a/mozilla/xpcom/ds/nsHashtable.cpp +++ b/mozilla/xpcom/ds/nsHashtable.cpp @@ -215,7 +215,7 @@ nsHashKey::~nsHashKey(void) MOZ_DECL_CTOR_COUNTER(nsHashtable); nsHashtable::nsHashtable(PRUint32 aInitSize, PRBool threadSafe) - : mLock(NULL) + : mLock(NULL), mEnumerating(PR_FALSE) { MOZ_COUNT_CTOR(nsHashtable); PRStatus status = PL_HashTableInit(&mHashtable, @@ -259,7 +259,9 @@ PRBool nsHashtable::Exists(nsHashKey *aKey) if (mLock) PR_Lock(mLock); - PLHashEntry **hep = PL_HashTableRawLookup(&mHashtable, hash, (void *) aKey); + PLHashEntry *const*hep = mEnumerating ? + PL_HashTableRawLookupConst(&mHashtable, hash, (void *) aKey) : + PL_HashTableRawLookup(&mHashtable, hash, (void *) aKey); if (mLock) PR_Unlock(mLock); @@ -273,6 +275,8 @@ void *nsHashtable::Put(nsHashKey *aKey, void *aData) { if (mLock) PR_Lock(mLock); + // shouldn't be adding an item during enumeration + PR_ASSERT(!mEnumerating); PLHashEntry **hep = PL_HashTableRawLookup(&mHashtable, hash, (void *) aKey); if ((he = *hep) != NULL) { @@ -297,8 +301,9 @@ void *nsHashtable::Get(nsHashKey *aKey) { if (mLock) PR_Lock(mLock); - void *ret = PL_HashTableLookup(&mHashtable, (void *) aKey); - + void *ret = mEnumerating ? + PL_HashTableLookupConst(&mHashtable, (void *) aKey) : + PL_HashTableLookup(&mHashtable, (void *) aKey); if (mLock) PR_Unlock(mLock); return ret; @@ -309,7 +314,9 @@ void *nsHashtable::Remove(nsHashKey *aKey) { PLHashEntry *he; if (mLock) PR_Lock(mLock); - + + // shouldn't be adding an item during enumeration + PR_ASSERT(!mEnumerating); PLHashEntry **hep = PL_HashTableRawLookup(&mHashtable, hash, (void *) aKey); void *res = NULL; @@ -344,10 +351,13 @@ nsHashtable * nsHashtable::Clone() { } void nsHashtable::Enumerate(nsHashtableEnumFunc aEnumFunc, void* closure) { + PRBool wasEnumerating = mEnumerating; + mEnumerating = PR_TRUE; _HashEnumerateArgs thunk; thunk.fn = aEnumFunc; thunk.arg = closure; PL_HashTableEnumerateEntries(&mHashtable, _hashEnumerate, &thunk); + mEnumerating = wasEnumerating; } static PRIntn PR_CALLBACK _hashEnumerateRemove(PLHashEntry *he, PRIntn i, void *arg) diff --git a/mozilla/xpcom/ds/nsHashtable.h b/mozilla/xpcom/ds/nsHashtable.h index 95582931ea1..740666a0e69 100644 --- a/mozilla/xpcom/ds/nsHashtable.h +++ b/mozilla/xpcom/ds/nsHashtable.h @@ -79,6 +79,7 @@ protected: // members PRLock* mLock; PLHashTable mHashtable; + PRBool mEnumerating; public: nsHashtable(PRUint32 aSize = 256, PRBool threadSafe = PR_FALSE);