diff --git a/dict.c b/dict.c index ae4966bc..3579f64d 100644 --- a/dict.c +++ b/dict.c @@ -135,6 +135,15 @@ static xmlRMutexPtr xmlDictMutex = NULL; */ static int xmlDictInitialized = 0; +#ifdef DICT_RANDOMIZATION +#ifdef HAVE_RAND_R +/* + * Internal data for random function, protected by xmlDictMutex + */ +unsigned int rand_seed = 0; +#endif +#endif + /** * xmlInitializeDict: * @@ -142,24 +151,50 @@ static int xmlDictInitialized = 0; * this function is not thread safe, initialization should * preferably be done once at startup */ -static int xmlInitializeDict(void) { +int xmlInitializeDict(void) { if (xmlDictInitialized) return(1); if ((xmlDictMutex = xmlNewRMutex()) == NULL) return(0); + xmlRMutexLock(xmlDictMutex); #ifdef DICT_RANDOMIZATION +#ifdef HAVE_RAND_R + rand_seed = time(NULL); + rand_r(& rand_seed); +#else srand(time(NULL)); +#endif #endif xmlDictInitialized = 1; + xmlRMutexUnlock(xmlDictMutex); return(1); } +#ifdef DICT_RANDOMIZATION +int __xmlRandom(void) { + int ret; + + if (xmlDictInitialized == 0) + xmlInitializeDict(); + + xmlRMutexLock(xmlDictMutex); +#ifdef HAVE_RAND_R + ret = rand_r(& rand_seed); +#else + ret = rand(); +#endif + xmlRMutexUnlock(xmlDictMutex); + return(ret); +} +#endif + /** * xmlDictCleanup: * - * Free the dictionary mutex. + * Free the dictionary mutex. Do not call unless sure the library + * is not in use anymore ! */ void xmlDictCleanup(void) { @@ -488,7 +523,7 @@ xmlDictCreate(void) { if (dict->dict) { memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry)); #ifdef DICT_RANDOMIZATION - dict->seed = rand(); + dict->seed = __xmlRandom(); #else dict->seed = 0; #endif diff --git a/hash.c b/hash.c index fe1424f2..15e1efe9 100644 --- a/hash.c +++ b/hash.c @@ -47,10 +47,6 @@ /* #define DEBUG_GROW */ -#ifdef HASH_RANDOMIZATION -static int hash_initialized = 0; -#endif - /* * A single entry in the hash table */ @@ -186,11 +182,7 @@ xmlHashCreate(int size) { if (table->table) { memset(table->table, 0, size * sizeof(xmlHashEntry)); #ifdef HASH_RANDOMIZATION - if (!hash_initialized) { - srand(time(NULL)); - hash_initialized = 1; - } - table->random_seed = rand(); + table->random_seed = __xmlRandom(); #endif return(table); } diff --git a/include/libxml/dict.h b/include/libxml/dict.h index abb8339c..59948689 100644 --- a/include/libxml/dict.h +++ b/include/libxml/dict.h @@ -24,6 +24,11 @@ extern "C" { typedef struct _xmlDict xmlDict; typedef xmlDict *xmlDictPtr; +/* + * Initializer + */ +XMLPUBFUN int XMLCALL xmlInitializeDict(void); + /* * Constructor and destructor. */ @@ -33,28 +38,28 @@ XMLPUBFUN xmlDictPtr XMLCALL xmlDictCreateSub(xmlDictPtr sub); XMLPUBFUN int XMLCALL xmlDictReference(xmlDictPtr dict); -XMLPUBFUN void XMLCALL +XMLPUBFUN void XMLCALL xmlDictFree (xmlDictPtr dict); /* * Lookup of entry in the dictionnary. */ -XMLPUBFUN const xmlChar * XMLCALL +XMLPUBFUN const xmlChar * XMLCALL xmlDictLookup (xmlDictPtr dict, const xmlChar *name, int len); -XMLPUBFUN const xmlChar * XMLCALL +XMLPUBFUN const xmlChar * XMLCALL xmlDictExists (xmlDictPtr dict, const xmlChar *name, int len); -XMLPUBFUN const xmlChar * XMLCALL +XMLPUBFUN const xmlChar * XMLCALL xmlDictQLookup (xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name); XMLPUBFUN int XMLCALL xmlDictOwns (xmlDictPtr dict, const xmlChar *str); -XMLPUBFUN int XMLCALL +XMLPUBFUN int XMLCALL xmlDictSize (xmlDictPtr dict); /* diff --git a/libxml.h b/libxml.h index dfc6c648..fa3aea4f 100644 --- a/libxml.h +++ b/libxml.h @@ -79,6 +79,13 @@ void __xmlGlobalInitMutexLock(void); void __xmlGlobalInitMutexUnlock(void); void __xmlGlobalInitMutexDestroy(void); +#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME) +/* + * internal thread safe random function + */ +int __xmlRandom(void); +#endif + #ifdef IN_LIBXML #ifdef __GNUC__ #ifdef PIC diff --git a/parser.c b/parser.c index 1b80a8c5..2c38faee 100644 --- a/parser.c +++ b/parser.c @@ -14178,6 +14178,7 @@ xmlInitParser(void) { (xmlGenericError == NULL)) initGenericErrorDefaultFunc(NULL); xmlInitMemory(); + xmlInitializeDict(); xmlInitCharEncodingHandlers(); xmlDefaultSAXHandlerInit(); xmlRegisterDefaultInputCallbacks();