Commit 1441251f authored by Daniel Veillard's avatar Daniel Veillard
Browse files

a single lock version mostly avoid the cost penalty of the lock in case of

* dict.c parser.c include/libxml/dict.h: a single lock version
  mostly avoid the cost penalty of the lock in case of low
  parallelism, so applying that version instead.
Daniel
parent 1bb16a18
Sat Jan 22 00:40:31 CET 2005 Daniel Veillard <daniel@veillard.com>
* dict.c parser.c include/libxml/dict.h: a single lock version
mostly avoid the cost penalty of the lock in case of low
parallelism, so applying that version instead.
Fri Jan 21 17:54:06 CET 2005 Daniel Veillard <daniel@veillard.com>
 
* dict.c: patch from Gary Coady to fix a race in dict reference
......
......@@ -70,6 +70,50 @@ struct _xmlDict {
struct _xmlDict *subdict;
};
/*
* A mutex for modifying the reference counter for shared
* dictionaries.
*/
static xmlRMutexPtr xmlDictMutex = NULL;
/*
* Whether the dictionary mutex was initialized.
*/
static int xmlDictInitialized = 0;
/**
* xmlInitializeCatalog:
*
* Do the dictionary mutex initialization.
* this function is not thread safe, initialization should
* preferably be done once at startup
*/
static int xmlInitializeDict() {
if (xmlDictInitialized)
return(1);
if ((xmlDictMutex = xmlNewRMutex()) == NULL)
return(0);
xmlDictInitialized = 1;
return(1);
}
/**
* xmlCatalogCleanup:
*
* Free the dictionary mutex.
*/
void
xmlDictCleanup(void) {
if (!xmlDictInitialized)
return;
xmlFreeRMutex(xmlDictMutex);
xmlDictInitialized = 0;
}
/*
* xmlDictAddString:
* @dict: the dictionnary
......@@ -278,7 +322,11 @@ xmlDictComputeQKey(const xmlChar *prefix, const xmlChar *name, int len)
xmlDictPtr
xmlDictCreate(void) {
xmlDictPtr dict;
if (!xmlDictInitialized)
if (!xmlInitializeDict())
return(NULL);
dict = xmlMalloc(sizeof(xmlDict));
if (dict) {
dict->ref_counter = 1;
......@@ -332,10 +380,14 @@ xmlDictCreateSub(xmlDictPtr sub) {
*/
int
xmlDictReference(xmlDictPtr dict) {
if (!xmlDictInitialized)
if (!xmlInitializeDict())
return(-1);
if (dict == NULL) return -1;
xmlRMutexLock(dict->mutex);
xmlRMutexLock(xmlDictMutex);
dict->ref_counter++;
xmlRMutexUnlock(dict->mutex);
xmlRMutexUnlock(xmlDictMutex);
return(0);
}
......@@ -451,15 +503,19 @@ xmlDictFree(xmlDictPtr dict) {
if (dict == NULL)
return;
if (!xmlDictInitialized)
if (!xmlInitializeDict())
return;
/* decrement the counter, it may be shared by a parser and docs */
xmlRMutexLock(dict->mutex);
xmlRMutexLock(xmlDictMutex);
dict->ref_counter--;
if (dict->ref_counter > 0) {
xmlRMutexUnlock(dict->mutex);
xmlRMutexUnlock(xmlDictMutex);
return;
}
xmlRMutexUnlock(dict->mutex);
xmlRMutexUnlock(xmlDictMutex);
if (dict->subdict != NULL) {
xmlDictFree(dict->subdict);
......
......@@ -56,6 +56,13 @@ XMLPUBFUN int XMLCALL
const xmlChar *str);
XMLPUBFUN int XMLCALL
xmlDictSize (xmlDictPtr dict);
/*
* Cleanup function
*/
XMLPUBFUN void XMLCALL
xmlDictCleanup (void);
#ifdef __cplusplus
}
#endif
......
......@@ -9035,7 +9035,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
xmlParseGetLasts(ctxt, &lastlt, &lastgt);
while (1) {
if ((ctxt->wellFormed != 1) && (ctxt->disableSAX == 1))
if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
return(0);
......@@ -9837,7 +9837,7 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
int terminate) {
if (ctxt == NULL)
return(XML_ERR_INTERNAL_ERROR);
if ((ctxt->wellFormed != 1) && (ctxt->disableSAX == 1))
if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
return(ctxt->errNo);
if (ctxt->instate == XML_PARSER_START)
xmlDetectSAX2(ctxt);
......@@ -9879,7 +9879,7 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
}
}
xmlParseTryOrFinish(ctxt, terminate);
if ((ctxt->wellFormed != 1) && (ctxt->disableSAX == 1))
if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
return(ctxt->errNo);
if (terminate) {
/*
......@@ -9909,7 +9909,6 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
}
ctxt->instate = XML_PARSER_EOF;
}
if (ctxt->wellFormed) return(0);
return((xmlParserErrors) ctxt->errNo);
}
......@@ -12159,6 +12158,7 @@ xmlCleanupParser(void) {
#ifdef LIBXML_CATALOG_ENABLED
xmlCatalogCleanup();
#endif
xmlDictCleanup();
xmlCleanupInputCallbacks();
#ifdef LIBXML_OUTPUT_ENABLED
xmlCleanupOutputCallbacks();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment