diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | dict.c | 68 | ||||
-rw-r--r-- | include/libxml/dict.h | 7 | ||||
-rw-r--r-- | parser.c | 8 |
4 files changed, 79 insertions, 10 deletions
@@ -1,3 +1,9 @@ +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 @@ -71,6 +71,50 @@ struct _xmlDict { }; /* + * 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 * @name: the name of the userdata @@ -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); diff --git a/include/libxml/dict.h b/include/libxml/dict.h index 6bf25fbf..abb8339c 100644 --- a/include/libxml/dict.h +++ b/include/libxml/dict.h @@ -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(); |