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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]