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