gareth 2005/02/25 01:16:51 Modified: c/src/xercesc/util RefHashTableOf.c Log: Fix thread safety issues. Jira #30380. Thanks to David Bertoni. Revision Changes Path 1.21 +36 -23 xml-xerces/c/src/xercesc/util/RefHashTableOf.c Index: RefHashTableOf.c =================================================================== RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/RefHashTableOf.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- RefHashTableOf.c 8 Feb 2005 09:21:11 -0000 1.20 +++ RefHashTableOf.c 25 Feb 2005 09:16:51 -0000 1.21 @@ -16,6 +16,9 @@ /** * $Log$ + * Revision 1.21 2005/02/25 09:16:51 gareth + * Fix thread safety issues. Jira #30380. Thanks to David Bertoni. + * * Revision 1.20 2005/02/08 09:21:11 amassari * Removed warnings * @@ -124,6 +127,7 @@ #include <xercesc/util/RefHashTableOf.hpp> #endif +#include <xercesc/util/Janitor.hpp> #include <xercesc/util/NullPointerException.hpp> #include <assert.h> #include <new> @@ -514,44 +518,53 @@ // --------------------------------------------------------------------------- template <class TVal> void RefHashTableOf<TVal>::rehash() { - unsigned int index; - unsigned int oldMod = fHashModulus; - fHashModulus *= 2; - - RefHashTableBucketElem<TVal>** oldBucketList = fBucketList; - - fBucketList = (RefHashTableBucketElem<TVal>**) fMemoryManager->allocate + const unsigned int newMod = fHashModulus * 2; + + RefHashTableBucketElem<TVal>** newBucketList = + (RefHashTableBucketElem<TVal>**) fMemoryManager->allocate ( - fHashModulus * sizeof(RefHashTableBucketElem<TVal>*) - );//new RefHashTableBucketElem<TVal>*[fHashModulus]; - for (index = 0; index < fHashModulus; index++) - fBucketList[index] = 0; + newMod * sizeof(RefHashTableBucketElem<TVal>*) + );//new RefHashTableBucketElem<TVal>*[newMod]; + + // Make sure the new bucket list is destroyed if an + // exception is thrown. + ArrayJanitor<RefHashTableBucketElem<TVal>*> guard(newBucketList, fMemoryManager); + + memset(newBucketList, 0, newMod * sizeof(newBucketList[0])); // Rehash all existing entries. - for (index = 0; index < oldMod; index++) + for (unsigned int index = 0; index < fHashModulus; index++) { // Get the bucket list head for this entry - RefHashTableBucketElem<TVal>* curElem = oldBucketList[index]; - RefHashTableBucketElem<TVal>* nextElem; + RefHashTableBucketElem<TVal>* curElem = fBucketList[index]; + while (curElem) { // Save the next element before we detach this one - nextElem = curElem->fNext; + RefHashTableBucketElem<TVal>* const nextElem = curElem->fNext; + + const unsigned int hashVal = fHash->getHashVal(curElem->fKey, newMod, fMemoryManager); + assert(hashVal < newMod); + + RefHashTableBucketElem<TVal>* const newHeadElem = newBucketList[hashVal]; - unsigned int hashVal = fHash->getHashVal(curElem->fKey, fHashModulus, fMemoryManager); - assert(hashVal < fHashModulus); - - RefHashTableBucketElem<TVal>* newHeadElem = fBucketList[hashVal]; - // Insert at the start of this bucket's list. curElem->fNext = newHeadElem; - fBucketList[hashVal] = curElem; - + newBucketList[hashVal] = curElem; + curElem = nextElem; } } - + + RefHashTableBucketElem<TVal>** const oldBucketList = fBucketList; + + // Everything is OK at this point, so update the + // member variables. + fBucketList = guard.release(); + fHashModulus = newMod; + + // Delete the old bucket list. fMemoryManager->deallocate(oldBucketList);//delete[] oldBucketList; }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]