You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by kn...@apache.org on 2003/10/17 18:44:34 UTC

cvs commit: xml-xerces/c/src/xercesc/util/regx TokenFactory.hpp TokenFactory.cpp RangeTokenMap.cpp

knoaman     2003/10/17 09:44:34

  Modified:    c/src/xercesc/util/regx TokenFactory.hpp TokenFactory.cpp
                        RangeTokenMap.cpp
  Log:
  Fix multithreading problem.
  
  Revision  Changes    Path
  1.8       +6 -2      xml-xerces/c/src/xercesc/util/regx/TokenFactory.hpp
  
  Index: TokenFactory.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/regx/TokenFactory.hpp,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- TokenFactory.hpp	16 May 2003 21:37:00 -0000	1.7
  +++ TokenFactory.hpp	17 Oct 2003 16:44:34 -0000	1.8
  @@ -138,6 +138,11 @@
   	Token* getGraphemePattern();
       MemoryManager* getMemoryManager() const;
   
  +    // -----------------------------------------------------------------------
  +    //  Notification that lazy data has been deleted
  +    // -----------------------------------------------------------------------
  +	static void reinitTokenFactoryMutex();
  +
   private:
       // -----------------------------------------------------------------------
       //  Unimplemented constructors and operators
  @@ -166,7 +171,6 @@
       //      Contains user created Token objects. Used for memory cleanup.
       // -----------------------------------------------------------------------
       static bool         fRangeInitialized;
  -    XMLMutex            fMutex;
       RefVectorOf<Token>* fTokens;
       Token*              fEmpty;
       Token*              fLineBegin;
  
  
  
  1.9       +52 -1     xml-xerces/c/src/xercesc/util/regx/TokenFactory.cpp
  
  Index: TokenFactory.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/regx/TokenFactory.cpp,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- TokenFactory.cpp	18 May 2003 14:02:06 -0000	1.8
  +++ TokenFactory.cpp	17 Oct 2003 16:44:34 -0000	1.9
  @@ -56,6 +56,9 @@
   
   /*
    * $Log$
  + * Revision 1.9  2003/10/17 16:44:34  knoaman
  + * Fix multithreading problem.
  + *
    * Revision 1.8  2003/05/18 14:02:06  knoaman
    * Memory manager implementation: pass per instance manager.
    *
  @@ -120,12 +123,60 @@
   #include <xercesc/util/regx/BlockRangeFactory.hpp>
   #include <xercesc/util/regx/RangeTokenMap.hpp>
   #include <xercesc/util/regx/RegxDefs.hpp>
  +#include <xercesc/util/XMLRegisterCleanup.hpp>
   
   XERCES_CPP_NAMESPACE_BEGIN
   
  +// ---------------------------------------------------------------------------
  +//  Static member data initialization
  +// ---------------------------------------------------------------------------
   bool TokenFactory::fRangeInitialized = false;
   
   // ---------------------------------------------------------------------------
  +//  Local static data
  +// ---------------------------------------------------------------------------
  +static bool               sTokFactoryMutexRegistered = false;
  +static XMLMutex*          sTokFactoryMutex = 0;
  +static XMLRegisterCleanup tokenFactoryMutexCleanup;
  +
  +// ---------------------------------------------------------------------------
  +//  Local, static functions
  +// ---------------------------------------------------------------------------
  +//  Cleanup for the TokenFactory mutex
  +void TokenFactory::reinitTokenFactoryMutex()
  +{
  +    delete sTokFactoryMutex;
  +    sTokFactoryMutex = 0;
  +    sTokFactoryMutexRegistered = false;
  +}
  +
  +//  We need to fault in this mutex. But, since its used for synchronization
  +//  itself, we have to do this the low level way using a compare and swap.
  +static XMLMutex& gTokenFactoryMutex()
  +{
  +    if (!sTokFactoryMutex)
  +    {
  +        XMLMutex* tmpMutex = new XMLMutex;
  +        if (XMLPlatformUtils::compareAndSwap((void**)&sTokFactoryMutex, tmpMutex, 0))
  +        {
  +            // Someone beat us to it, so let's clean up ours
  +            delete tmpMutex;
  +        }
  +
  +        // Now lock it and try to register it
  +        XMLMutexLock lock(sTokFactoryMutex);
  +
  +        // If we got here first, then register it and set the registered flag
  +        if (!sTokFactoryMutexRegistered)
  +        {
  +			tokenFactoryMutexCleanup.registerCleanup(TokenFactory::reinitTokenFactoryMutex);
  +            sTokFactoryMutexRegistered = true;
  +        }
  +    }
  +    return *sTokFactoryMutex;
  +}
  +
  +// ---------------------------------------------------------------------------
   //  TokenFactory: Constructors and Destructor
   // ---------------------------------------------------------------------------
   TokenFactory::TokenFactory(MemoryManager* const manager) :
  @@ -451,7 +502,7 @@
   
       // Use a faux scope to synchronize while we do this
       {
  -        XMLMutexLock lockInit(&fMutex);
  +        XMLMutexLock lockInit(&gTokenFactoryMutex());
   
           if (!fRangeInitialized) {
   
  
  
  
  1.6       +35 -26    xml-xerces/c/src/xercesc/util/regx/RangeTokenMap.cpp
  
  Index: RangeTokenMap.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/regx/RangeTokenMap.cpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- RangeTokenMap.cpp	18 May 2003 14:02:06 -0000	1.5
  +++ RangeTokenMap.cpp	17 Oct 2003 16:44:34 -0000	1.6
  @@ -56,6 +56,9 @@
   
   /*
    * $Log$
  + * Revision 1.6  2003/10/17 16:44:34  knoaman
  + * Fix multithreading problem.
  + *
    * Revision 1.5  2003/05/18 14:02:06  knoaman
    * Memory manager implementation: pass per instance manager.
    *
  @@ -168,43 +171,49 @@
   //  RangeTokenMap: Getter methods
   // ---------------------------------------------------------------------------
   RangeToken* RangeTokenMap::getRange(const XMLCh* const keyword,
  -								   const bool complement) {
  +								    const bool complement) {
   
  -	if (fTokenRegistry == 0 || fRangeMap == 0 || fCategories == 0)
  -		return 0;
  +    if (fTokenRegistry == 0 || fRangeMap == 0 || fCategories == 0)
  +        return 0;
   
       if (!fTokenRegistry->containsKey(keyword))
  -		return 0;
  +        return 0;
   
  -	RangeTokenElemMap* elemMap = 0;
  +    RangeTokenElemMap* elemMap = fTokenRegistry->get(keyword);
  +    RangeToken* rangeTok = elemMap->getRangeToken(complement);
   
  -	// Use a faux scope to synchronize while we do this
  +    if (!rangeTok)
       {
           XMLMutexLock lockInit(&fMutex);
   
  -		elemMap = fTokenRegistry->get(keyword);
  -		RangeToken* rangeTok = 0;
  +        // make sure that it was not created while we were locked
  +        rangeTok = elemMap->getRangeToken(complement);
   
  -		if (elemMap->getRangeToken() == 0) {
  -		
  -			unsigned int categId = elemMap->getCategoryId();
  -			const XMLCh* categName = fCategories->getValueForId(categId);
  -			RangeFactory* rangeFactory = fRangeMap->get(categName);
  -
  -			if (rangeFactory == 0)
  -				return 0;
  -
  -			rangeFactory->buildRanges();
  -		}
  -
  -		if (complement && ((rangeTok = elemMap->getRangeToken()) != 0)) {
  -			elemMap->setRangeToken((RangeToken*)
  -									RangeToken::complementRanges(rangeTok, fTokenFactory),
  -									complement);
  -		}
  +        if (!rangeTok)
  +        {
  +            rangeTok = elemMap->getRangeToken();
  +            if (!rangeTok)
  +            {
  +                unsigned int categId = elemMap->getCategoryId();
  +                const XMLCh* categName = fCategories->getValueForId(categId);
  +                RangeFactory* rangeFactory = fRangeMap->get(categName);
  +
  +                if (rangeFactory == 0)
  +                    return 0;
  +
  +                rangeFactory->buildRanges();
  +                rangeTok = elemMap->getRangeToken();
  +            }
  +
  +            if (complement)
  +            {
  +                rangeTok = (RangeToken*) RangeToken::complementRanges(rangeTok, fTokenFactory);
  +                elemMap->setRangeToken(rangeTok , complement);
  +            }
  +        }
       }
   
  -	return (elemMap == 0) ? 0 : elemMap->getRangeToken(complement);
  +    return rangeTok;
   }
   
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org