summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2005-01-21 23:53:26 +0000
committerDaniel Veillard <veillard@src.gnome.org>2005-01-21 23:53:26 +0000
commit1441251f851f011cd34edaff9095374d5e6f7b14 (patch)
tree7ccb5db8ea516bcc7fb667c3fbceb6bce31baf4b
parent1bb16a188852d9cdca9ac99ee41c2ccc84cf0fd0 (diff)
downloadlibxml2-1441251f851f011cd34edaff9095374d5e6f7b14.tar.gz
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
-rw-r--r--ChangeLog6
-rw-r--r--dict.c68
-rw-r--r--include/libxml/dict.h7
-rw-r--r--parser.c8
4 files changed, 79 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 598ec6d3..65e5691c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/dict.c b/dict.c
index a78ccee7..fd3e5317 100644
--- a/dict.c
+++ b/dict.c
@@ -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
diff --git a/parser.c b/parser.c
index 84b230f2..a9961383 100644
--- a/parser.c
+++ b/parser.c
@@ -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();