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()
diff --git a/dict.c b/dict.c
index ae4966b..3579f64 100644
--- a/dict.c
+++ b/dict.c
@@ -135,6 +135,15 @@
*/
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 @@
* 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 @@
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