1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-21 14:53:44 +03:00

Cleanup on randomization

tsan reported that rand() is not thread safe, so create
a thread safe wrapper, use rand_r() if available.
Consolidate the function, initialization and cleanup in
dict.c and make sure it is initialized in xmlInitParser()
This commit is contained in:
Daniel Veillard
2012-05-18 15:41:31 +08:00
parent 9d9685ad88
commit 379ebc1d77
5 changed files with 57 additions and 17 deletions

41
dict.c
View File

@@ -135,6 +135,15 @@ static xmlRMutexPtr xmlDictMutex = NULL;
*/ */
static int xmlDictInitialized = 0; 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: * xmlInitializeDict:
* *
@@ -142,24 +151,50 @@ static int xmlDictInitialized = 0;
* this function is not thread safe, initialization should * this function is not thread safe, initialization should
* preferably be done once at startup * preferably be done once at startup
*/ */
static int xmlInitializeDict(void) { int xmlInitializeDict(void) {
if (xmlDictInitialized) if (xmlDictInitialized)
return(1); return(1);
if ((xmlDictMutex = xmlNewRMutex()) == NULL) if ((xmlDictMutex = xmlNewRMutex()) == NULL)
return(0); return(0);
xmlRMutexLock(xmlDictMutex);
#ifdef DICT_RANDOMIZATION #ifdef DICT_RANDOMIZATION
#ifdef HAVE_RAND_R
rand_seed = time(NULL);
rand_r(& rand_seed);
#else
srand(time(NULL)); srand(time(NULL));
#endif
#endif #endif
xmlDictInitialized = 1; xmlDictInitialized = 1;
xmlRMutexUnlock(xmlDictMutex);
return(1); 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: * xmlDictCleanup:
* *
* Free the dictionary mutex. * Free the dictionary mutex. Do not call unless sure the library
* is not in use anymore !
*/ */
void void
xmlDictCleanup(void) { xmlDictCleanup(void) {
@@ -488,7 +523,7 @@ xmlDictCreate(void) {
if (dict->dict) { if (dict->dict) {
memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry)); memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
#ifdef DICT_RANDOMIZATION #ifdef DICT_RANDOMIZATION
dict->seed = rand(); dict->seed = __xmlRandom();
#else #else
dict->seed = 0; dict->seed = 0;
#endif #endif

10
hash.c
View File

@@ -47,10 +47,6 @@
/* #define DEBUG_GROW */ /* #define DEBUG_GROW */
#ifdef HASH_RANDOMIZATION
static int hash_initialized = 0;
#endif
/* /*
* A single entry in the hash table * A single entry in the hash table
*/ */
@@ -186,11 +182,7 @@ xmlHashCreate(int size) {
if (table->table) { if (table->table) {
memset(table->table, 0, size * sizeof(xmlHashEntry)); memset(table->table, 0, size * sizeof(xmlHashEntry));
#ifdef HASH_RANDOMIZATION #ifdef HASH_RANDOMIZATION
if (!hash_initialized) { table->random_seed = __xmlRandom();
srand(time(NULL));
hash_initialized = 1;
}
table->random_seed = rand();
#endif #endif
return(table); return(table);
} }

View File

@@ -24,6 +24,11 @@ extern "C" {
typedef struct _xmlDict xmlDict; typedef struct _xmlDict xmlDict;
typedef xmlDict *xmlDictPtr; typedef xmlDict *xmlDictPtr;
/*
* Initializer
*/
XMLPUBFUN int XMLCALL xmlInitializeDict(void);
/* /*
* Constructor and destructor. * Constructor and destructor.
*/ */
@@ -33,28 +38,28 @@ XMLPUBFUN xmlDictPtr XMLCALL
xmlDictCreateSub(xmlDictPtr sub); xmlDictCreateSub(xmlDictPtr sub);
XMLPUBFUN int XMLCALL XMLPUBFUN int XMLCALL
xmlDictReference(xmlDictPtr dict); xmlDictReference(xmlDictPtr dict);
XMLPUBFUN void XMLCALL XMLPUBFUN void XMLCALL
xmlDictFree (xmlDictPtr dict); xmlDictFree (xmlDictPtr dict);
/* /*
* Lookup of entry in the dictionnary. * Lookup of entry in the dictionnary.
*/ */
XMLPUBFUN const xmlChar * XMLCALL XMLPUBFUN const xmlChar * XMLCALL
xmlDictLookup (xmlDictPtr dict, xmlDictLookup (xmlDictPtr dict,
const xmlChar *name, const xmlChar *name,
int len); int len);
XMLPUBFUN const xmlChar * XMLCALL XMLPUBFUN const xmlChar * XMLCALL
xmlDictExists (xmlDictPtr dict, xmlDictExists (xmlDictPtr dict,
const xmlChar *name, const xmlChar *name,
int len); int len);
XMLPUBFUN const xmlChar * XMLCALL XMLPUBFUN const xmlChar * XMLCALL
xmlDictQLookup (xmlDictPtr dict, xmlDictQLookup (xmlDictPtr dict,
const xmlChar *prefix, const xmlChar *prefix,
const xmlChar *name); const xmlChar *name);
XMLPUBFUN int XMLCALL XMLPUBFUN int XMLCALL
xmlDictOwns (xmlDictPtr dict, xmlDictOwns (xmlDictPtr dict,
const xmlChar *str); const xmlChar *str);
XMLPUBFUN int XMLCALL XMLPUBFUN int XMLCALL
xmlDictSize (xmlDictPtr dict); xmlDictSize (xmlDictPtr dict);
/* /*

View File

@@ -79,6 +79,13 @@ void __xmlGlobalInitMutexLock(void);
void __xmlGlobalInitMutexUnlock(void); void __xmlGlobalInitMutexUnlock(void);
void __xmlGlobalInitMutexDestroy(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 IN_LIBXML
#ifdef __GNUC__ #ifdef __GNUC__
#ifdef PIC #ifdef PIC

View File

@@ -14178,6 +14178,7 @@ xmlInitParser(void) {
(xmlGenericError == NULL)) (xmlGenericError == NULL))
initGenericErrorDefaultFunc(NULL); initGenericErrorDefaultFunc(NULL);
xmlInitMemory(); xmlInitMemory();
xmlInitializeDict();
xmlInitCharEncodingHandlers(); xmlInitCharEncodingHandlers();
xmlDefaultSAXHandlerInit(); xmlDefaultSAXHandlerInit();
xmlRegisterDefaultInputCallbacks(); xmlRegisterDefaultInputCallbacks();