- include/libxml/globals.h include/libxml/threads.h threads.c
  testThreads.c: far more testing, cleaning up bugs
- *.c : make sure globals.h is always included.
Daniel
diff --git a/ChangeLog b/ChangeLog
index 69d9f94..eb73e8e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Wed Oct 17 11:56:25 EDT 2001 Daniel Veillard <daniel@veillard.com>
+
+	* include/libxml/globals.h include/libxml/threads.h threads.c
+	  testThreads.c: far more testing, cleaning up bugs
+	* *.c : make sure globals.h is always included.
+
 Wed Oct 17 17:41:41 CEST 2001 Daniel Veillard <daniel@veillard.com>
 
 	* HTMLparser.c: try to get rid of parser loops for good.
diff --git a/DOCBparser.c b/DOCBparser.c
index b8809fc..5ea8b0a 100644
--- a/DOCBparser.c
+++ b/DOCBparser.c
@@ -45,6 +45,7 @@
 #include <libxml/valid.h>
 #include <libxml/xmlIO.h>
 #include <libxml/uri.h>
+#include <libxml/globals.h>
 
 /*
  * Internal description of an SGML entity
diff --git a/HTMLparser.c b/HTMLparser.c
index f263dbf..6b69b20 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -40,6 +40,7 @@
 #include <libxml/encoding.h>
 #include <libxml/valid.h>
 #include <libxml/xmlIO.h>
+#include <libxml/globals.h>
 
 #define HTML_MAX_NAMELEN 1000
 #define HTML_PARSER_BIG_BUFFER_SIZE 1000
diff --git a/HTMLtree.c b/HTMLtree.c
index 030dce6..7041dbe 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -24,6 +24,7 @@
 #include <libxml/valid.h>
 #include <libxml/xmlerror.h>
 #include <libxml/parserInternals.h>
+#include <libxml/globals.h>
 
 /************************************************************************
  *									*
diff --git a/SAX.c b/SAX.c
index b7cf784..e854748 100644
--- a/SAX.c
+++ b/SAX.c
@@ -23,6 +23,7 @@
 #include <libxml/uri.h>
 #include <libxml/valid.h>
 #include <libxml/HTMLtree.h>
+#include <libxml/globals.h>
 
 /* #define DEBUG_SAX */
 /* #define DEBUG_SAX_TREE */
@@ -1713,7 +1714,7 @@
 void
 xmlDefaultSAXHandlerInit(void)
 {
-	initxmlDefaultSAXHandler(&xmlDefaultSAXHandler, xmlGetWarningsDefaultValue);
+    initxmlDefaultSAXHandler(&xmlDefaultSAXHandler, xmlGetWarningsDefaultValue);
 }
 
 #ifdef LIBXML_HTML_ENABLED
@@ -1820,7 +1821,7 @@
 void
 docbDefaultSAXHandlerInit(void)
 {
-	initdocbDefaultSAXHandler(&docbDefaultSAXHandler);
+    initdocbDefaultSAXHandler(&docbDefaultSAXHandler);
 }
 
 #endif /* LIBXML_DOCB_ENABLED */
diff --git a/catalog.c b/catalog.c
index 287d4aa..40e91a5 100644
--- a/catalog.c
+++ b/catalog.c
@@ -38,6 +38,7 @@
 #include <libxml/catalog.h>
 #include <libxml/xmlerror.h>
 #include <libxml/threads.h>
+#include <libxml/globals.h>
 
 #define MAX_DELEGATE	50
 
@@ -1217,7 +1218,7 @@
 
     if (xmlDebugCatalogs)
 	xmlGenericError(xmlGenericErrorContext,
-		"Parsing catalog %s\n", filename);
+		"%d Parsing catalog %s\n", xmlGetThreadId(), filename);
 
     cur = xmlDocGetRootElement(doc);
     if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&
diff --git a/debugXML.c b/debugXML.c
index dbdd1f3..b1461a9 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -26,6 +26,7 @@
 #include <libxml/HTMLtree.h>
 #include <libxml/HTMLparser.h>
 #include <libxml/xmlerror.h>
+#include <libxml/globals.h>
 
 /**
  * xmlDebugDumpString:
diff --git a/entities.c b/entities.c
index 09f46d3..05c525c 100644
--- a/entities.c
+++ b/entities.c
@@ -17,6 +17,7 @@
 #include <libxml/entities.h>
 #include <libxml/parser.h>
 #include <libxml/xmlerror.h>
+#include <libxml/globals.h>
 
 /*
  * The XML predefined entities.
diff --git a/error.c b/error.c
index d663689..0ba84cf 100644
--- a/error.c
+++ b/error.c
@@ -12,6 +12,7 @@
 #include <libxml/parser.h>
 #include <libxml/xmlerror.h>
 #include <libxml/xmlmemory.h>
+#include <libxml/globals.h>
 
 #define XML_GET_VAR_STR(msg, str) {				\
     int       size;						\
diff --git a/globals.c b/globals.c
index 69a84f2..cfa5ca6 100644
--- a/globals.c
+++ b/globals.c
@@ -18,19 +18,17 @@
 #endif
 #include <string.h>
 
+#include <libxml/xmlversion.h>
+#include <libxml/globals.h>
 #include <libxml/xmlmemory.h>
 
+/* #define DEBUG_GLOBALS */
+
 /*
  * Helpful Macro
  */
-#ifdef WITH_PTHREAD_H
-#if defined(SOLARIS)
-#define THR_MAIN(tid) (-1 == thr_main() || tid == thr_main())
-#else
-#define THR_MAIN(tid) (tid == 0 || tid == 1024)
-#endif
-
-#define IS_MAIN_THREAD (THR_MAIN(pthread_self()))
+#ifdef LIBXML_THREAD_ENABLED
+#define IS_MAIN_THREAD (xmlIsMainThread())
 #else
 #define IS_MAIN_THREAD 1
 #endif
@@ -41,8 +39,6 @@
  * 									*
  ************************************************************************/
 
-const char *xmlParserVersion = LIBXML_VERSION_STRING;
-
 /*
  * Memory allocation routines
  */
@@ -93,6 +89,8 @@
 #undef	xmlMemStrdup
 #undef	xmlRealloc
 
+const char *xmlParserVersion = LIBXML_VERSION_STRING;
+
 /*
  * Buffers stuff
  */
@@ -252,11 +250,19 @@
 void
 xmlInitializeGlobalState(xmlGlobalStatePtr gs)
 {
+#ifdef DEBUG_GLOBALS
+    fprintf(stderr, "Initializing globals at %lu for thread %d\n",
+	    (unsigned long) gs, xmlGetThreadId());
+#endif
+
     /*
      * Perform initialisation as required by libxml
      */
+    initxmlDefaultSAXHandler(&gs->xmlDefaultSAXHandler, 1);
     initdocbDefaultSAXHandler(&gs->docbDefaultSAXHandler);
     inithtmlDefaultSAXHandler(&gs->htmlDefaultSAXHandler);
+    initGenericErrorDefaultFunc(&gs->xmlGenericError);
+
     gs->oldXMLWDcompatibility = 0;
     gs->xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
     gs->xmlDefaultBufferSize = BASE_BUFFER_SIZE;
@@ -277,7 +283,6 @@
     gs->xmlRealloc = (xmlReallocFunc) realloc;
     gs->xmlMemStrdup = (xmlStrdupFunc) strdup;
 #endif
-    initGenericErrorDefaultFunc(&gs->xmlGenericError);
     gs->xmlGenericErrorContext = NULL;
     gs->xmlGetWarningsDefaultValue = 1;
     gs->xmlIndentTreeOutput = 0;
diff --git a/hash.c b/hash.c
index ed10394..4ea4b2b 100644
--- a/hash.c
+++ b/hash.c
@@ -24,6 +24,7 @@
 #include <libxml/xmlmemory.h>
 #include <libxml/parser.h>
 #include <libxml/xmlerror.h>
+#include <libxml/globals.h>
 
 #define MAX_HASH_LEN 8
 
diff --git a/include/libxml/globals.h b/include/libxml/globals.h
index f1e46a9..72454c9 100644
--- a/include/libxml/globals.h
+++ b/include/libxml/globals.h
@@ -57,6 +57,11 @@
 {
 	const char *xmlParserVersion;
 
+	xmlSAXLocator xmlDefaultSAXLocator;
+	xmlSAXHandler xmlDefaultSAXHandler;
+	xmlSAXHandler docbDefaultSAXHandler;
+	xmlSAXHandler htmlDefaultSAXHandler;
+
 	xmlFreeFunc xmlFree;
 	xmlMallocFunc xmlMalloc;
 	xmlStrdupFunc xmlMemStrdup;
@@ -65,11 +70,6 @@
 	xmlGenericErrorFunc xmlGenericError;
 	void *xmlGenericErrorContext;
 
-	xmlSAXLocator xmlDefaultSAXLocator;
-	xmlSAXHandler xmlDefaultSAXHandler;
-	xmlSAXHandler docbDefaultSAXHandler;
-	xmlSAXHandler htmlDefaultSAXHandler;
-
 	int oldXMLWDcompatibility;
 
 	xmlBufferAllocationScheme xmlBufferAllocScheme;
diff --git a/include/libxml/threads.h b/include/libxml/threads.h
index d20b8ff..c50c0f0 100644
--- a/include/libxml/threads.h
+++ b/include/libxml/threads.h
@@ -43,6 +43,8 @@
 void			xmlInitThreads	(void);
 void			xmlLockLibrary	(void);
 void			xmlUnlockLibrary(void);
+int			xmlGetThreadId	(void);
+int			xmlIsMainThread	(void);
 void			xmlCleanupThreads(void);
 xmlGlobalStatePtr	xmlGetGlobalState(void);
 
diff --git a/list.c b/list.c
index b0acf7d..5abe2ee 100644
--- a/list.c
+++ b/list.c
@@ -21,6 +21,7 @@
 #include <string.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/list.h>
+#include <libxml/globals.h>
 
 /*
  * Type definition are kept internal
diff --git a/nanoftp.c b/nanoftp.c
index a83e897..9dc04cf 100644
--- a/nanoftp.c
+++ b/nanoftp.c
@@ -59,6 +59,7 @@
 #include <libxml/parser.h>
 #include <libxml/xmlerror.h>
 #include <libxml/nanoftp.h>
+#include <libxml/globals.h>
 
 /* #define DEBUG_FTP 1  */
 #ifdef STANDALONE
diff --git a/nanohttp.c b/nanohttp.c
index 9c4b84f..be92b32 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -68,6 +68,7 @@
 #include <libxml/xmlmemory.h>
 #include <libxml/parser.h> /* for xmlStr(n)casecmp() */
 #include <libxml/nanohttp.h>
+#include <libxml/globals.h>
 
 /**
  * A couple portability macros
diff --git a/parser.c b/parser.c
index 15a0f69..df21992 100644
--- a/parser.c
+++ b/parser.c
@@ -10186,7 +10186,8 @@
 
 void
 xmlInitParser(void) {
-    if (xmlParserInitialized) return;
+    if (xmlParserInitialized != 0)
+	return;
 
     initGenericErrorDefaultFunc(NULL);
     xmlInitThreads();
diff --git a/parserInternals.c b/parserInternals.c
index 68553c2..9832a52 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -50,6 +50,7 @@
 #ifdef LIBXML_CATALOG_ENABLED
 #include <libxml/catalog.h>
 #endif
+#include <libxml/globals.h>
 
 void xmlUpgradeOldNs(xmlDocPtr doc);
 
@@ -2234,7 +2235,7 @@
     ctxt->space = &ctxt->spaceTab[0];
 
     ctxt->sax = sax;
-    memcpy(sax, &xmlDefaultSAXHandler, sizeof(xmlSAXHandler));
+    initxmlDefaultSAXHandler(sax, xmlGetWarningsDefaultValue);
 
     ctxt->userData = ctxt;
     ctxt->myDoc = NULL;
diff --git a/testDocbook.c b/testDocbook.c
index 8822fa3..5f697cd 100644
--- a/testDocbook.c
+++ b/testDocbook.c
@@ -35,6 +35,7 @@
 #include <libxml/DOCBparser.h>
 #include <libxml/tree.h>
 #include <libxml/debugXML.h>
+#include <libxml/globals.h>
 
 #ifdef LIBXML_DEBUG_ENABLED
 static int debug = 0;
diff --git a/testHTML.c b/testHTML.c
index 6ec56a2..dbfccc3 100644
--- a/testHTML.c
+++ b/testHTML.c
@@ -35,6 +35,7 @@
 #include <libxml/HTMLtree.h>
 #include <libxml/debugXML.h>
 #include <libxml/xmlerror.h>
+#include <libxml/globals.h>
 
 #ifdef LIBXML_DEBUG_ENABLED
 static int debug = 0;
diff --git a/testThreads.c b/testThreads.c
index e0c06fb..044c90e 100644
--- a/testThreads.c
+++ b/testThreads.c
@@ -1,4 +1,5 @@
 #include <stdlib.h>
+#include <stdio.h>
 #include <features.h>
 #include <libxml/xmlversion.h>
 
@@ -26,13 +27,24 @@
     "test/threads/invalid.xml",
 };
 
+const char *Okay = "OK";
+const char *Failed = "Failed";
+
+#ifndef xmlDoValidityCheckingDefaultValue
+#error xmlDoValidityCheckingDefaultValue is not a macro
+#endif
+#ifndef xmlGenericErrorContext
+#error xmlGenericErrorContext is not a macro
+#endif
+
 static void *
 thread_specific_data(void *private_data)
 {
     xmlDocPtr myDoc;
     const char *filename = (const char *) private_data;
+    int okay = 1;
 
-    if (!strcmp(filename, "test/thread/invalid.xml") == 0) {
+    if (!strcmp(filename, "test/threads/invalid.xml")) {
         xmlDoValidityCheckingDefaultValue = 0;
         xmlGenericErrorContext = stdout;
     } else {
@@ -42,36 +54,72 @@
     myDoc = xmlParseFile(filename);
     if (myDoc) {
         xmlFreeDoc(myDoc);
-    } else
-        printf("parse failed\n");
-    if (!strcmp(filename, "test/thread/invalid.xml") == 0) {
-        if (xmlDoValidityCheckingDefaultValue != 0)
-	    printf("ValidityCheckingDefaultValue override failed\n");
-        if (xmlGenericErrorContext != stdout)
-	    printf("ValidityCheckingDefaultValue override failed\n");
     } else {
-        if (xmlDoValidityCheckingDefaultValue != 1)
-	    printf("ValidityCheckingDefaultValue override failed\n");
-        if (xmlGenericErrorContext != stderr)
-	    printf("ValidityCheckingDefaultValue override failed\n");
+        printf("parse failed\n");
+	okay = 0;
     }
-    return (NULL);
+    if (!strcmp(filename, "test/threads/invalid.xml")) {
+        if (xmlDoValidityCheckingDefaultValue != 0) {
+	    printf("ValidityCheckingDefaultValue override failed\n");
+	    okay = 0;
+	}
+        if (xmlGenericErrorContext != stdout) {
+	    printf("xmlGenericErrorContext override failed\n");
+	    okay = 0;
+	}
+    } else {
+        if (xmlDoValidityCheckingDefaultValue != 1) {
+	    printf("ValidityCheckingDefaultValue override failed\n");
+	    okay = 0;
+	}
+        if (xmlGenericErrorContext != stderr) {
+	    printf("xmlGenericErrorContext override failed\n");
+	    okay = 0;
+	}
+    }
+    if (okay == 0)
+	return((void *) Failed);
+    return ((void *) Okay);
 }
 
 int
 main()
 {
-    unsigned int i;
+    unsigned int i, repeat;
     unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
+    void *results[MAX_ARGC];
+    int ret;
 
     xmlInitParser();
-    xmlLoadCatalog(catalog);
+    for (repeat = 0;repeat < 10000;repeat++) {
+	xmlLoadCatalog(catalog);
 
-    for (i = 0; i < num_threads; i++)
-        pthread_create(&tid[i], 0, thread_specific_data, (void *) testfiles[i]);
-    for (i = 0; i < num_threads; i++)
-        pthread_join(tid[i], NULL);
+	for (i = 0; i < num_threads; i++) {
+	    results[i] = NULL;
+	    tid[i] = -1;
+	}
 
+	for (i = 0; i < num_threads; i++) {
+	    ret = pthread_create(&tid[i], 0, thread_specific_data,
+				 (void *) testfiles[i]);
+	    if (ret != 0) {
+		perror("pthread_create");
+		exit(1);
+	    }
+	}
+	for (i = 0; i < num_threads; i++) {
+	    ret = pthread_join(tid[i], &results[i]);
+	    if (ret != 0) {
+		perror("pthread_join");
+		exit(1);
+	    }
+	}
+
+	xmlCatalogCleanup();
+	for (i = 0; i < num_threads; i++)
+	    if (results[i] != (void *) Okay)
+		printf("Thread %d handling %s failed\n", i, testfiles[i]);
+    }
     xmlCleanupParser();
     xmlMemoryDump();
     return (0);
diff --git a/testURI.c b/testURI.c
index dcbda1f..2233dc7 100644
--- a/testURI.c
+++ b/testURI.c
@@ -14,6 +14,7 @@
 
 #include <libxml/xmlmemory.h>
 #include <libxml/uri.h>
+#include <libxml/globals.h>
 
 int main(int argc, char **argv) {
     int i, ret, arg = 1;
diff --git a/testXPath.c b/testXPath.c
index bfbb56a..ee0ebae 100644
--- a/testXPath.c
+++ b/testXPath.c
@@ -36,6 +36,7 @@
 #include <libxml/parserInternals.h>
 #include <libxml/xpathInternals.h>
 #include <libxml/xmlerror.h>
+#include <libxml/globals.h>
 #if defined(LIBXML_XPTR_ENABLED)
 #include <libxml/xpointer.h>
 static int xptr = 0;
diff --git a/threads.c b/threads.c
index 69dfe93..4f1b0b8 100644
--- a/threads.c
+++ b/threads.c
@@ -332,6 +332,23 @@
  ************************************************************************/
 
 /**
+ * xmlGetThreadId:
+ *
+ * xmlGetThreadId() find the current thread ID number
+ *
+ * Returns the current thread ID number
+ */
+int
+xmlGetThreadId(void)
+{
+#ifdef HAVE_PTHREAD_H
+    return((int) pthread_self());
+#else
+    return((int) 0);
+#endif
+}
+
+/**
  * xmlIsMainThread:
  *
  * xmlIsMainThread() check wether the current thread is the main thread.
diff --git a/tree.c b/tree.c
index 99c3989..f41337b 100644
--- a/tree.c
+++ b/tree.c
@@ -33,6 +33,7 @@
 #include <libxml/valid.h>
 #include <libxml/xmlerror.h>
 #include <libxml/parserInternals.h>
+#include <libxml/globals.h>
 
 xmlNsPtr xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
 
diff --git a/valid.c b/valid.c
index c27c3c2..a8b4b4c 100644
--- a/valid.c
+++ b/valid.c
@@ -22,6 +22,7 @@
 #include <libxml/parserInternals.h>
 #include <libxml/xmlerror.h>
 #include <libxml/list.h>
+#include <libxml/globals.h>
 
 /* #define DEBUG_VALID_ALGO */
 
diff --git a/xinclude.c b/xinclude.c
index 813e3e6..620e426 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -24,6 +24,7 @@
 #include <libxml/xpointer.h>
 #include <libxml/parserInternals.h>
 #include <libxml/xmlerror.h>
+#include <libxml/globals.h>
 
 #ifdef LIBXML_XINCLUDE_ENABLED
 #include <libxml/xinclude.h>
diff --git a/xlink.c b/xlink.c
index 2631961..7715d2e 100644
--- a/xlink.c
+++ b/xlink.c
@@ -35,6 +35,7 @@
 #include <libxml/parser.h>
 #include <libxml/valid.h>
 #include <libxml/xlink.h>
+#include <libxml/globals.h>
 
 #define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/")
 #define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/")
diff --git a/xmlIO.c b/xmlIO.c
index b8be560..86b4701 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -73,6 +73,7 @@
 #ifdef LIBXML_CATALOG_ENABLED
 #include <libxml/catalog.h>
 #endif
+#include <libxml/globals.h>
 
 #ifdef VMS
 #define xmlRegisterDefaultInputCallbacks xmlRegisterDefInputCallbacks
diff --git a/xmlcatalog.c b/xmlcatalog.c
index b76719d..e9238a4 100644
--- a/xmlcatalog.c
+++ b/xmlcatalog.c
@@ -27,6 +27,7 @@
 #include <libxml/uri.h>
 #include <libxml/catalog.h>
 #include <libxml/parser.h>
+#include <libxml/globals.h>
 
 static int shell = 0;
 static int sgml = 0;
diff --git a/xmllint.c b/xmllint.c
index 22f8ea3..7725c43 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -68,6 +68,7 @@
 #ifdef LIBXML_CATALOG_ENABLED
 #include <libxml/catalog.h>
 #endif
+#include <libxml/globals.h>
 
 #ifdef LIBXML_DEBUG_ENABLED
 static int debug = 0;
diff --git a/xpath.c b/xpath.c
index f8966d1..63edcc0 100644
--- a/xpath.c
+++ b/xpath.c
@@ -52,6 +52,7 @@
 #endif
 #include <libxml/xmlerror.h>
 #include <libxml/threads.h>
+#include <libxml/globals.h>
 
 /* #define DEBUG */
 /* #define DEBUG_STEP */
diff --git a/xpointer.c b/xpointer.c
index 692ea71..70a1983 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -27,6 +27,7 @@
 #include <libxml/xpath.h>
 #include <libxml/xpathInternals.h>
 #include <libxml/xmlerror.h>
+#include <libxml/globals.h>
 
 #ifdef LIBXML_XPTR_ENABLED