You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by ga...@apache.org on 2005/02/25 10:16:51 UTC
cvs commit: xml-xerces/c/src/xercesc/util RefHashTableOf.c
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: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org