Re: [xml] per thread globals initialization patch
- From: Stéphane Bidoul <stephane bidoul softwareag com>
- To: veillard redhat com
- Cc: xml gnome org
- Subject: Re: [xml] per thread globals initialization patch
- Date: Thu, 15 May 2003 22:16:23 +0200
Daniel Veillard wrote:
Hum, the definitions for xmlInitGlobals() and xmlCleanupGlobals()
seems to be missing , could you send these so I can commit :-)
Daniel
Ooops, sorry. Forgot to include globals.c in the patch...
Here it is, along with the python test case.
-sbi
Index: globals.c
===================================================================
RCS file: /cvs/gnome/gnome-xml/globals.c,v
retrieving revision 1.23
diff -c -b -r1.23 globals.c
*** globals.c 21 Apr 2003 21:36:39 -0000 1.23
--- globals.c 15 May 2003 20:11:14 -0000
***************
*** 21,26 ****
--- 21,27 ----
#include <libxml/globals.h>
#include <libxml/xmlmemory.h>
+ #include <libxml/threads.h>
/* #define DEBUG_GLOBALS */
***************
*** 33,38 ****
--- 34,54 ----
#define IS_MAIN_THREAD 1
#endif
+ /*
+ * Mutex to protect "ForNewThreads" variables
+ */
+ static xmlMutexPtr xmlThrDefMutex = NULL;
+
+ void xmlInitGlobals()
+ {
+ xmlThrDefMutex = xmlNewMutex();
+ }
+
+ void xmlCleanupGlobals()
+ {
+ xmlFreeMutex(xmlThrDefMutex);
+ }
+
/************************************************************************
* *
* All the user accessible global variables of the library *
***************
*** 150,161 ****
--- 166,179 ----
* XML_BUFFER_ALLOC_EXACT
*/
xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
+ static xmlBufferAllocationScheme xmlBufferAllocSchemeThrDef = XML_BUFFER_ALLOC_EXACT;
/**
* xmlDefaultBufferSize:
*
* Global setting, default buffer size. Default value is BASE_BUFFER_SIZE
*/
int xmlDefaultBufferSize = BASE_BUFFER_SIZE;
+ static int xmlDefaultBufferSizeThrDef = BASE_BUFFER_SIZE;
/*
* Parser defaults
***************
*** 175,180 ****
--- 193,199 ----
* Disabled by default
*/
int xmlParserDebugEntities = 0;
+ static int xmlParserDebugEntitiesThrDef = 0;
/**
* xmlDoValidityCheckingDefaultValue:
*
***************
*** 182,187 ****
--- 201,207 ----
* Disabled by default.
*/
int xmlDoValidityCheckingDefaultValue = 0;
+ static int xmlDoValidityCheckingDefaultValueThrDef = 0;
/**
* xmlGetWarningsDefaultValue:
*
***************
*** 189,194 ****
--- 209,215 ----
* Activated by default.
*/
int xmlGetWarningsDefaultValue = 1;
+ static int xmlGetWarningsDefaultValueThrDef = 1;
/**
* xmlLoadExtDtdDefaultValue:
*
***************
*** 197,202 ****
--- 218,224 ----
* Disabled by default.
*/
int xmlLoadExtDtdDefaultValue = 0;
+ static int xmlLoadExtDtdDefaultValueThrDef = 0;
/**
* xmlPedanticParserDefaultValue:
*
***************
*** 204,209 ****
--- 226,232 ----
* Disabled by default.
*/
int xmlPedanticParserDefaultValue = 0;
+ static int xmlPedanticParserDefaultValueThrDef = 0;
/**
* xmlLineNumbersDefaultValue:
*
***************
*** 213,218 ****
--- 236,242 ----
* applicaton.
*/
int xmlLineNumbersDefaultValue = 0;
+ static int xmlLineNumbersDefaultValueThrDef = 0;
/**
* xmlKeepBlanksDefaultValue:
*
***************
*** 223,228 ****
--- 247,253 ----
* for some applications since this was libxml1 default behaviour.
*/
int xmlKeepBlanksDefaultValue = 1;
+ static int xmlKeepBlanksDefaultValueThrDef = 1;
/**
* xmlSubstituteEntitiesDefaultValue:
*
***************
*** 233,241 ****
--- 258,269 ----
* engine does not handle entities references transparently.
*/
int xmlSubstituteEntitiesDefaultValue = 0;
+ static int xmlSubstituteEntitiesDefaultValueThrDef = 0;
xmlRegisterNodeFunc xmlRegisterNodeDefaultValue = NULL;
+ static xmlRegisterNodeFunc xmlRegisterNodeDefaultValueThrDef = NULL;
xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue = NULL;
+ static xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValueThrDef = NULL;
/*
* Error handling
***************
*** 252,263 ****
--- 280,293 ----
* Global setting: function used for generic error callbacks
*/
xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc;
+ static xmlGenericErrorFunc xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
/**
* xmlGenericErrorContext:
*
* Global setting passed to generic error callbacks
*/
void *xmlGenericErrorContext = NULL;
+ static void *xmlGenericErrorContextThrDef = NULL;
/*
* output defaults
***************
*** 269,274 ****
--- 299,305 ----
* Enabled by default
*/
int xmlIndentTreeOutput = 1;
+ static int xmlIndentTreeOutputThrDef = 1;
/**
* xmlTreeIndentString:
***************
*** 276,281 ****
--- 307,313 ----
* The string used to do one-level indent. By default is equal to " " (two spaces)
*/
const char *xmlTreeIndentString = " ";
+ static const char *xmlTreeIndentStringThrDef = " ";
/**
* xmlSaveNoEmptyTags:
***************
*** 286,291 ****
--- 318,324 ----
* Disabled by default
*/
int xmlSaveNoEmptyTags = 0;
+ int xmlSaveNoEmptyTagsThrDef = 0;
/**
* xmlDefaultSAXHandler:
***************
*** 427,432 ****
--- 460,466 ----
/*
* Perform initialization as required by libxml
*/
+ xmlMutexLock(xmlThrDefMutex);
#ifdef LIBXML_DOCB_ENABLED
initdocbDefaultSAXHandler(&gs->docbDefaultSAXHandler);
***************
*** 434,450 ****
#ifdef LIBXML_HTML_ENABLED
inithtmlDefaultSAXHandler(&gs->htmlDefaultSAXHandler);
#endif
- initGenericErrorDefaultFunc(&gs->xmlGenericError);
gs->oldXMLWDcompatibility = 0;
! gs->xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
! gs->xmlDefaultBufferSize = BASE_BUFFER_SIZE;
initxmlDefaultSAXHandler(&gs->xmlDefaultSAXHandler, 1);
gs->xmlDefaultSAXLocator.getPublicId = getPublicId;
gs->xmlDefaultSAXLocator.getSystemId = getSystemId;
gs->xmlDefaultSAXLocator.getLineNumber = getLineNumber;
gs->xmlDefaultSAXLocator.getColumnNumber = getColumnNumber;
! gs->xmlDoValidityCheckingDefaultValue = 0;
#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
gs->xmlFree = (xmlFreeFunc) xmlMemFree;
gs->xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
--- 468,484 ----
#ifdef LIBXML_HTML_ENABLED
inithtmlDefaultSAXHandler(&gs->htmlDefaultSAXHandler);
#endif
gs->oldXMLWDcompatibility = 0;
! gs->xmlBufferAllocScheme = xmlBufferAllocSchemeThrDef;
! gs->xmlDefaultBufferSize = xmlDefaultBufferSizeThrDef;
initxmlDefaultSAXHandler(&gs->xmlDefaultSAXHandler, 1);
gs->xmlDefaultSAXLocator.getPublicId = getPublicId;
gs->xmlDefaultSAXLocator.getSystemId = getSystemId;
gs->xmlDefaultSAXLocator.getLineNumber = getLineNumber;
gs->xmlDefaultSAXLocator.getColumnNumber = getColumnNumber;
! gs->xmlDoValidityCheckingDefaultValue =
! xmlDoValidityCheckingDefaultValueThrDef;
#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
gs->xmlFree = (xmlFreeFunc) xmlMemFree;
gs->xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
***************
*** 458,478 ****
gs->xmlRealloc = (xmlReallocFunc) realloc;
gs->xmlMemStrdup = (xmlStrdupFunc) xmlStrdup;
#endif
! gs->xmlGenericErrorContext = NULL;
! gs->xmlGetWarningsDefaultValue = 1;
! gs->xmlIndentTreeOutput = 1;
! gs->xmlTreeIndentString = " ";
! gs->xmlKeepBlanksDefaultValue = 1;
! gs->xmlLineNumbersDefaultValue = 0;
! gs->xmlLoadExtDtdDefaultValue = 0;
! gs->xmlParserDebugEntities = 0;
gs->xmlParserVersion = LIBXML_VERSION_STRING;
! gs->xmlPedanticParserDefaultValue = 0;
! gs->xmlSaveNoEmptyTags = 0;
! gs->xmlSubstituteEntitiesDefaultValue = 0;
! gs->xmlRegisterNodeDefaultValue = NULL;
! gs->xmlDeregisterNodeDefaultValue = NULL;
}
/**
--- 492,527 ----
gs->xmlRealloc = (xmlReallocFunc) realloc;
gs->xmlMemStrdup = (xmlStrdupFunc) xmlStrdup;
#endif
! gs->xmlGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef;
! gs->xmlIndentTreeOutput = xmlIndentTreeOutputThrDef;
! gs->xmlTreeIndentString = xmlTreeIndentStringThrDef;
! gs->xmlKeepBlanksDefaultValue = xmlKeepBlanksDefaultValueThrDef;
! gs->xmlLineNumbersDefaultValue = xmlLineNumbersDefaultValueThrDef;
! gs->xmlLoadExtDtdDefaultValue = xmlLoadExtDtdDefaultValueThrDef;
! gs->xmlParserDebugEntities = xmlParserDebugEntitiesThrDef;
gs->xmlParserVersion = LIBXML_VERSION_STRING;
! gs->xmlPedanticParserDefaultValue = xmlPedanticParserDefaultValueThrDef;
! gs->xmlSaveNoEmptyTags = xmlSaveNoEmptyTagsThrDef;
! gs->xmlSubstituteEntitiesDefaultValue =
! xmlSubstituteEntitiesDefaultValueThrDef;
!
! gs->xmlGenericError = xmlGenericErrorThrDef;
! gs->xmlGenericErrorContext = xmlGenericErrorContextThrDef;
! gs->xmlRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef;
! gs->xmlDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef;
! xmlMutexUnlock(xmlThrDefMutex);
! }
!
! void
! xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
! xmlMutexLock(xmlThrDefMutex);
! xmlGenericErrorContextThrDef = ctx;
! if (handler != NULL)
! xmlGenericErrorThrDef = handler;
! else
! xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
! xmlMutexUnlock(xmlThrDefMutex);
}
/**
***************
*** 493,498 ****
--- 542,562 ----
return(old);
}
+ xmlRegisterNodeFunc
+ xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func)
+ {
+ xmlRegisterNodeFunc old;
+
+ xmlMutexLock(xmlThrDefMutex);
+ old = xmlRegisterNodeDefaultValueThrDef;
+
+ __xmlRegisterCallbacks = 1;
+ xmlRegisterNodeDefaultValueThrDef = func;
+ xmlMutexUnlock(xmlThrDefMutex);
+
+ return(old);
+ }
+
/**
* xmlDeregisterNodeDefault:
* @func: function pointer to the new DeregisterNodeFunc
***************
*** 511,516 ****
--- 575,595 ----
return(old);
}
+ xmlDeregisterNodeFunc
+ xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func)
+ {
+ xmlDeregisterNodeFunc old;
+
+ xmlMutexLock(xmlThrDefMutex);
+ old = xmlDeregisterNodeDefaultValueThrDef;
+
+ __xmlRegisterCallbacks = 1;
+ xmlDeregisterNodeDefaultValueThrDef = func;
+ xmlMutexUnlock(xmlThrDefMutex);
+
+ return(old);
+ }
+
#ifdef LIBXML_DOCB_ENABLED
#undef docbDefaultSAXHandler
***************
*** 558,563 ****
--- 637,650 ----
else
return (&xmlGetGlobalState()->xmlBufferAllocScheme);
}
+ xmlBufferAllocationScheme xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v) {
+ xmlBufferAllocationScheme ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlBufferAllocSchemeThrDef;
+ xmlBufferAllocSchemeThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlDefaultBufferSize
int *
***************
*** 567,572 ****
--- 654,667 ----
else
return (&xmlGetGlobalState()->xmlDefaultBufferSize);
}
+ int xmlThrDefDefaultBufferSize(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlDefaultBufferSizeThrDef;
+ xmlDefaultBufferSizeThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlDefaultSAXHandler
xmlSAXHandler *
***************
*** 594,599 ****
--- 689,702 ----
else
return (&xmlGetGlobalState()->xmlDoValidityCheckingDefaultValue);
}
+ int xmlThrDefDoValidityCheckingDefaultValue(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlDoValidityCheckingDefaultValueThrDef;
+ xmlDoValidityCheckingDefaultValueThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlGenericError
xmlGenericErrorFunc *
***************
*** 621,626 ****
--- 724,737 ----
else
return (&xmlGetGlobalState()->xmlGetWarningsDefaultValue);
}
+ int xmlThrDefGetWarningsDefaultValue(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlGetWarningsDefaultValueThrDef;
+ xmlGetWarningsDefaultValueThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlIndentTreeOutput
int *
***************
*** 630,635 ****
--- 741,754 ----
else
return (&xmlGetGlobalState()->xmlIndentTreeOutput);
}
+ int xmlThrDefIndentTreeOutput(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlIndentTreeOutputThrDef;
+ xmlIndentTreeOutputThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlTreeIndentString
const char * *
***************
*** 639,644 ****
--- 758,771 ----
else
return (&xmlGetGlobalState()->xmlTreeIndentString);
}
+ const char * xmlThrDefTreeIndentString(const char * v) {
+ const char * ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlTreeIndentStringThrDef;
+ xmlTreeIndentStringThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlKeepBlanksDefaultValue
int *
***************
*** 648,653 ****
--- 775,788 ----
else
return (&xmlGetGlobalState()->xmlKeepBlanksDefaultValue);
}
+ int xmlThrDefKeepBlanksDefaultValue(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlKeepBlanksDefaultValueThrDef;
+ xmlKeepBlanksDefaultValueThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlLineNumbersDefaultValue
int *
***************
*** 657,662 ****
--- 792,805 ----
else
return (&xmlGetGlobalState()->xmlLineNumbersDefaultValue);
}
+ int xmlThrDefLineNumbersDefaultValue(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlLineNumbersDefaultValueThrDef;
+ xmlLineNumbersDefaultValueThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlLoadExtDtdDefaultValue
int *
***************
*** 666,671 ****
--- 809,822 ----
else
return (&xmlGetGlobalState()->xmlLoadExtDtdDefaultValue);
}
+ int xmlThrDefLoadExtDtdDefaultValue(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlLoadExtDtdDefaultValueThrDef;
+ xmlLoadExtDtdDefaultValueThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlParserDebugEntities
int *
***************
*** 675,680 ****
--- 826,839 ----
else
return (&xmlGetGlobalState()->xmlParserDebugEntities);
}
+ int xmlThrDefParserDebugEntities(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlParserDebugEntitiesThrDef;
+ xmlParserDebugEntitiesThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlParserVersion
const char * *
***************
*** 693,698 ****
--- 852,865 ----
else
return (&xmlGetGlobalState()->xmlPedanticParserDefaultValue);
}
+ int xmlThrDefPedanticParserDefaultValue(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlPedanticParserDefaultValueThrDef;
+ xmlPedanticParserDefaultValueThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlSaveNoEmptyTags
int *
***************
*** 702,707 ****
--- 869,882 ----
else
return (&xmlGetGlobalState()->xmlSaveNoEmptyTags);
}
+ int xmlThrDefSaveNoEmptyTags(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlSaveNoEmptyTagsThrDef;
+ xmlSaveNoEmptyTagsThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlSubstituteEntitiesDefaultValue
int *
***************
*** 711,716 ****
--- 886,899 ----
else
return (&xmlGetGlobalState()->xmlSubstituteEntitiesDefaultValue);
}
+ int xmlThrDefSubstituteEntitiesDefaultValue(int v) {
+ int ret;
+ xmlMutexLock(xmlThrDefMutex);
+ ret = xmlSubstituteEntitiesDefaultValueThrDef;
+ xmlSubstituteEntitiesDefaultValueThrDef = v;
+ xmlMutexUnlock(xmlThrDefMutex);
+ return ret;
+ }
#undef xmlRegisterNodeDefaultValue
xmlRegisterNodeFunc *
import string, sys, time
import thread
from threading import Thread, Lock
import libxml2
THREADS_COUNT = 15
failed = 0
class ErrorHandler:
def __init__(self):
self.errors = []
self.lock = Lock()
def handler(self,ctx,str):
self.lock.acquire()
self.errors.append(str)
self.lock.release()
def getLineNumbersDefault():
old = libxml2.lineNumbersDefault(0)
libxml2.lineNumbersDefault(old)
return old
def test(expectedLineNumbersDefault):
time.sleep(1)
global failed
# check a per thread-global
if expectedLineNumbersDefault != getLineNumbersDefault():
failed = 1
print "FAILED to obtain correct value for " \
"lineNumbersDefault in thread %d" % thread.get_ident()
# check ther global error handler
# (which is NOT per-thread in the python bindings)
try:
doc = libxml2.parseFile("bad.xml")
except:
pass
else:
assert "failed"
# global error handler
eh = ErrorHandler()
libxml2.registerErrorHandler(eh.handler,"")
# set on the main thread only
libxml2.lineNumbersDefault(1)
test(1)
ec = len(eh.errors)
if ec == 0:
print "FAILED: should have obtained errors"
sys.exit(1)
ts = []
for i in range(THREADS_COUNT):
# expect 0 for lineNumbersDefault because
# the new value has been set on the main thread only
ts.append(Thread(target=test,args=(0,)))
for t in ts:
t.start()
for t in ts:
t.join()
if len(eh.errors) != ec+THREADS_COUNT*ec:
print "FAILED: did not obtain the correct number of errors"
sys.exit(1)
# set lineNumbersDefault for future new threads
libxml2.thrDefLineNumbersDefaultValue(1)
ts = []
for i in range(THREADS_COUNT):
# expect 1 for lineNumbersDefault
ts.append(Thread(target=test,args=(1,)))
for t in ts:
t.start()
for t in ts:
t.join()
if len(eh.errors) != ec+THREADS_COUNT*ec*2:
print "FAILED: did not obtain the correct number of errors"
sys.exit(1)
if failed:
print "FAILED"
sys.exit(1)
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print "OK"
else:
print "Memory leak %d bytes" % (libxml2.debugMemory(1))
libxml2.dumpMemory()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]