started integrating the core of the thread support not activated yet but

* Makefile.am include/libxml/Makefile.am
  include/libxml/globals.h globals.c  include/libxml/threads.h
  threads.c build_glob.py global.data xmlcatalog.c acconfig.h
  configure.in: started integrating the core of the thread support
  not activated yet but half integrated. The code should still
  compile and work anyway.
Daniel
This commit is contained in:
Daniel Veillard 2001-10-12 17:29:10 +00:00
parent b44025c72b
commit b847864fc2
14 changed files with 1411 additions and 7 deletions

View File

@ -1,3 +1,12 @@
Fri Oct 12 19:25:55 CEST 2001 Daniel Veillard <daniel@veillard.com>
* Makefile.am include/libxml/Makefile.am
include/libxml/globals.h globals.c include/libxml/threads.h
threads.c build_glob.py global.data xmlcatalog.c acconfig.h
configure.in: started integrating the core of the thread support
not activated yet but half integrated. The code should still
compile and work anyway.
Fri Oct 12 00:53:03 CEST 2001 Daniel Veillard <daniel@veillard.com>
* HTMLtree.c catalog.c debugXML.c entities.c nanoftp.c

View File

@ -5,7 +5,7 @@ AUTOMAKE_OPTIONS=no-dependencies
SUBDIRS = include . doc example
INCLUDES = -I@srcdir@/include -I$(top_builddir)/include @Z_CFLAGS@
INCLUDES = -I@srcdir@/include -I$(top_builddir)/include @THREAD_CFLAGS@ @Z_CFLAGS@
noinst_PROGRAMS=testSAX testHTML testXPath testURI testDocbook
@ -23,19 +23,19 @@ libxml2_la_SOURCES = SAX.c entities.c encoding.c error.c parserInternals.c \
parser.c tree.c hash.c list.c xmlIO.c xmlmemory.c uri.c \
valid.c xlink.c HTMLparser.c HTMLtree.c debugXML.c xpath.c \
xpointer.c xinclude.c nanohttp.c nanoftp.c DOCBparser.c \
catalog.c strio.c trio.c
catalog.c threads.c strio.c trio.c
else
libxml2_la_SOURCES = SAX.c entities.c encoding.c error.c parserInternals.c \
parser.c tree.c hash.c list.c xmlIO.c xmlmemory.c uri.c \
valid.c xlink.c HTMLparser.c HTMLtree.c debugXML.c xpath.c \
xpointer.c xinclude.c nanohttp.c nanoftp.c DOCBparser.c \
catalog.c
catalog.c threads.c
endif
DEPS = $(top_builddir)/libxml2.la
LDADDS = $(top_builddir)/libxml2.la @Z_LIBS@ $(ICONV_LIBS) -lm
LDADDS = $(top_builddir)/libxml2.la @THREAD_LIBS@ @Z_LIBS@ $(ICONV_LIBS) -lm
man_MANS = xmllint.1 xml2-config.1 libxml.4

View File

@ -7,3 +7,5 @@
#undef HAVE_LIBHISTORY
#undef HAVE_LIBREADLINE
#undef SOCKLEN_T
#undef HAVE_LIBPTHREAD
#undef HAVE_PTHREAD_H

107
build_glob.py Executable file
View File

@ -0,0 +1,107 @@
#! /usr/bin/env python
###
#
# build_glob.py : Build the global_functions.h and global_functions.c
# files which are required to implement the user
# interface to global variables now that thread specific
# data (TSD) is used to emulate global state.
#
# See Copyright for the status of this software.
# Gary.Pennington@sun.com
###
import os, string
class globvar:
def __init__(self, type, name):
self.type=type
self.name=name
def writeline(file, line=None):
if line:
file.write(line)
file.write(os.linesep)
if __name__ == "__main__":
globals={}
global_data=open("global.data").readlines()
global_code=open("globals.c").readlines()
global_hdr=open("include/libxml/globals.h").readlines()
global_functions_hdr=open("include/libxml/globals.h", "w+")
global_functions_impl=open("globals.c", "w+")
#
# Rebuild the beginning of the file up to the
# Automatically generated string
#
for line in global_hdr:
if line[-len(os.linesep):] == os.linesep:
line = line[:-len(os.linesep)]
if line == " * Automatically generated by build_glob.py.":
break
writeline(global_functions_hdr, line)
writeline(global_functions_hdr, " * Automatically generated by build_glob.py.")
writeline(global_functions_hdr, " * Do not modify the previous line.")
writeline(global_functions_hdr, " */")
writeline(global_functions_hdr)
for line in global_code:
if line[-len(os.linesep):] == os.linesep:
line = line[:-len(os.linesep)]
if line == " * Automatically generated by build_glob.py.":
break
writeline(global_functions_impl, line)
writeline(global_functions_impl, " * Automatically generated by build_glob.py.")
writeline(global_functions_impl, " * Do not modify the previous line.")
writeline(global_functions_impl, " */")
writeline(global_functions_impl)
# Now process the data and write it to the appropriate output file
for line in global_data:
if line[0]=='#':
continue
if line[-len(os.linesep):] == os.linesep:
line = line[:-len(os.linesep)]
fields = string.split(line, ",")
# Update the header file
writeline(global_functions_hdr)
writeline(global_functions_hdr, "#ifdef LIBXML_THREAD_ENABLED")
global_functions_hdr.write("extern "+fields[0]+" *")
if len(fields) == 3:
global_functions_hdr.write("(*")
global_functions_hdr.write("__"+fields[1]+"(void)")
if len(fields) == 3:
global_functions_hdr.write(")"+fields[2])
writeline(global_functions_hdr,";")
writeline(global_functions_hdr,"#define "+fields[1]+" \\")
writeline(global_functions_hdr,"(*(__"+fields[1]+"()))")
writeline(global_functions_hdr,"#else")
if len(fields) == 3:
writeline(global_functions_hdr,"extern "+fields[0]+" "+fields[1]+fields[2]+";")
else:
writeline(global_functions_hdr,"extern "+fields[0]+" "+fields[1]+";")
writeline(global_functions_hdr,"#endif")
# Update the implementation file
writeline(global_functions_impl)
writeline(global_functions_impl, "extern "+fields[0]+" "+fields[1]+";")
writeline(global_functions_impl, "#undef\t"+fields[1])
writeline(global_functions_impl, fields[0]+" *")
if len(fields) == 3:
global_functions_impl.write("(*")
global_functions_impl.write("__"+fields[1]+"(void)")
if len(fields) == 3:
writeline(global_functions_impl, ")[]")
writeline(global_functions_impl, " {")
writeline(global_functions_impl, " if (IS_MAIN_THREAD)")
writeline(global_functions_impl, "\treturn (&"+fields[1]+");")
writeline(global_functions_impl, " else")
writeline(global_functions_impl, "\treturn (&get_glob_struct()->"+fields[1]+");")
writeline(global_functions_impl, "}")
# Terminate the header file with appropriate boilerplate
writeline(global_functions_hdr)
writeline(global_functions_hdr, "#ifdef __cplusplus")
writeline(global_functions_hdr, "}")
writeline(global_functions_hdr, "#endif")
writeline(global_functions_hdr)
writeline(global_functions_hdr, "#endif /* __XML_GLOBALS_H */")

View File

@ -15,6 +15,8 @@
#undef HAVE_LIBHISTORY
#undef HAVE_LIBREADLINE
#undef SOCKLEN_T
#undef HAVE_LIBPTHREAD
#undef HAVE_PTHREAD_H
/* Define if you have the _stat function. */
#undef HAVE__STAT
@ -91,6 +93,9 @@
/* Define if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
/* Define if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H

View File

@ -243,10 +243,32 @@ AM_CONDITIONAL(WITH_TRIO_SOURCES, test "${NEED_TRIO}" = "1")
AC_SUBST(WITH_TRIO)
dnl
dnl Aloow to disable various pieces
dnl Aloow to enable/disable various pieces
dnl
AC_ARG_WITH(history, [ --with-history Add history support to xmllint shell(off)])
THREAD_LIBS=""
WITH_THREADS=0
THREAD_CFLAGS=""
AC_ARG_WITH(threads, [ --with-threads Add multithread support(off)])
if test "$with_threads" = "yes" ; then
echo Enabling multithreaded support
AC_CHECK_HEADER(pthread.h,
AC_CHECK_LIB(pthread, pthread_mutex_lock,[
THREAD_LIBS="-lpthread"
AC_DEFINE(HAVE_LIBPTHREAD)
AC_DEFINE(HAVE_PTHREAD_H)
WITH_THREADS=1]))
if test "$WITH_THREADS" = "1" ; then
THREAD_CFLAGS="$XML_CFLAGS -D_REENTRANT"
fi
fi
AC_SUBST(THREAD_LIBS)
AC_SUBST(WITH_THREADS)
AC_SUBST(THREAD_CFLAGS)
AC_ARG_WITH(history, [ --with-history Add history support to xmllint shell(off)])
if test "$with_history" = "yes" ; then
echo Enabling xmllint shell history
dnl check for terminal library. this is a very cool solution

27
global.data Normal file
View File

@ -0,0 +1,27 @@
xmlSAXHandler,docbDefaultSAXHandler
xmlSAXHandler,htmlDefaultSAXHandler
int,oldXMLWDcompatibility
xmlBufferAllocationScheme,xmlBufferAllocScheme
int,xmlDefaultBufferSize
xmlSAXHandler,xmlDefaultSAXHandler
xmlSAXLocator,xmlDefaultSAXLocator
int,xmlDoValidityCheckingDefaultValue
xmlFreeFunc,xmlFree
xmlGenericErrorFunc,xmlGenericError
void *,xmlGenericErrorContext
int,xmlGetWarningsDefaultValue
int,xmlIndentTreeOutput
int,xmlKeepBlanksDefaultValue
int,xmlLineNumbersDefaultValue
int,xmlLoadExtDtdDefaultValue
xmlMallocFunc,xmlMalloc
xmlStrdupFunc,xmlMemStrdup
int,xmlParserDebugEntities
const char *,xmlParserVersion
int,xmlPedanticParserDefaultValue
xmlReallocFunc,xmlRealloc
int,xmlSaveNoEmptyTags
#const xmlChar,xmlStringComment,[]
#const xmlChar,xmlStringText,[]
#const xmlChar,xmlStringTextNoenc,[]
int,xmlSubstituteEntitiesDefaultValue

498
globals.c Normal file
View File

@ -0,0 +1,498 @@
/*
* globals.c: definition and handling of the set of global variables
* of the library
*
* The bottom of this file is automatically generated by build_glob.py
* based on the description file global.data
*
* See Copyright for the status of this software.
*
* Gary Pennington <Gary.Pennington@uk.sun.com>
* daniel@veillard.com
*/
#include "libxml.h"
#include <libxml/threads.h>
#include <libxml/globals.h>
/*
* 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()))
#else
#define IS_MAIN_THREAD 1
#endif
/************************************************************************
* *
* All the user accessible global variables of the library *
* *
************************************************************************/
const char *xmlParserVersion = LIBXML_VERSION_STRING;
/*
* Memory allocation routines
*/
#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
#else
xmlFreeFunc xmlFree = (xmlFreeFunc) free;
xmlMallocFunc xmlMalloc = (xmlMallocFunc) malloc;
xmlReallocFunc xmlRealloc = (xmlReallocFunc) realloc;
xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) strdup;
#endif
/*
* Buffers stuff
*/
xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
int xmlDefaultBufferSize = BASE_BUFFER_SIZE;
/*
* Parser defaults
*/
int oldXMLWDcompatibility = 0; /* DEPRECATED */
int xmlParserDebugEntities = 0;
int xmlDoValidityCheckingDefaultValue = 0;
int xmlGetWarningsDefaultValue = 1;
int xmlLoadExtDtdDefaultValue = 0;
int xmlPedanticParserDefaultValue = 0;
int xmlLineNumbersDefaultValue = 0;
int xmlKeepBlanksDefaultValue = 1;
int xmlSubstituteEntitiesDefaultValue = 0;
/*
* Error handling
*/
/* xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc; */
/* Must initialize xmlGenericError in xmlInitParser */
xmlGenericErrorFunc xmlGenericError;
void *xmlGenericErrorContext = NULL;
/*
* output defaults
*/
int xmlIndentTreeOutput = 0;
int xmlSaveNoEmptyTags = 0;
/*
* Default handler for XML, builds the DOM tree
*/
xmlSAXHandler xmlDefaultSAXHandler = {
internalSubset,
isStandalone,
hasInternalSubset,
hasExternalSubset,
resolveEntity,
getEntity,
entityDecl,
notationDecl,
attributeDecl,
elementDecl,
unparsedEntityDecl,
setDocumentLocator,
startDocument,
endDocument,
startElement,
endElement,
reference,
characters,
characters,
processingInstruction,
comment,
xmlParserWarning,
xmlParserError,
xmlParserError,
getParameterEntity,
cdataBlock,
externalSubset,
0
};
/*
* The default SAX Locator.
*/
xmlSAXLocator xmlDefaultSAXLocator = {
getPublicId, getSystemId, getLineNumber, getColumnNumber
};
#ifdef LIBXML_HTML_ENABLED
/*
* Default handler for HTML, builds the DOM tree
*/
xmlSAXHandler htmlDefaultSAXHandler = {
internalSubset,
NULL,
NULL,
NULL,
NULL,
getEntity,
NULL,
NULL,
NULL,
NULL,
NULL,
setDocumentLocator,
startDocument,
endDocument,
startElement,
endElement,
NULL,
characters,
ignorableWhitespace,
NULL,
comment,
xmlParserWarning,
xmlParserError,
xmlParserError,
getParameterEntity,
cdataBlock,
NULL,
0
};
#endif /* LIBXML_HTML_ENABLED */
#ifdef LIBXML_DOCB_ENABLED
/*
* Default handler for SGML DocBook, builds the DOM tree
*/
xmlSAXHandler docbDefaultSAXHandler = {
internalSubset,
isStandalone,
hasInternalSubset,
hasExternalSubset,
resolveEntity,
getEntity,
entityDecl,
NULL,
NULL,
NULL,
NULL,
setDocumentLocator,
startDocument,
endDocument,
startElement,
endElement,
reference,
characters,
ignorableWhitespace,
NULL,
comment,
xmlParserWarning,
xmlParserError,
xmlParserError,
getParameterEntity,
NULL,
NULL,
0
};
#endif /* LIBXML_DOCB_ENABLED */
/**
* xmlInitializeGlobalState:
* @gs: a pointer to a newly allocated global state
*
* xmlInitializeGlobalState() initialize a global state with all the
* default values of the library.
*/
void
xmlInitializeGlobalState(xmlGlobalStatePtr gs)
{
/*
* Perform initialisation as required by libxml
*/
initdocbDefaultSAXHandler(&gs->docbDefaultSAXHandler);
inithtmlDefaultSAXHandler(&gs->htmlDefaultSAXHandler);
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;
gs->xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
gs->xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
#else
gs->xmlFree = (xmlFreeFunc) free;
gs->xmlMalloc = (xmlMallocFunc) malloc;
gs->xmlRealloc = (xmlReallocFunc) realloc;
gs->xmlMemStrdup = (xmlStrdupFunc) strdup;
#endif
initGenericErrorDefaultFunc(&gs->xmlGenericError);
gs->xmlGenericErrorContext = NULL;
gs->xmlGetWarningsDefaultValue = 1;
gs->xmlIndentTreeOutput = 0;
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;
}
/*
* Everything starting from the line below is
* Automatically generated by build_glob.py.
* Do not modify the previous line.
*/
extern xmlSAXHandler docbDefaultSAXHandler;
#undef docbDefaultSAXHandler
xmlSAXHandler *
__docbDefaultSAXHandler(void) {
if (IS_MAIN_THREAD)
return (&docbDefaultSAXHandler);
else
return (&get_glob_struct()->docbDefaultSAXHandler);
}
extern xmlSAXHandler htmlDefaultSAXHandler;
#undef htmlDefaultSAXHandler
xmlSAXHandler *
__htmlDefaultSAXHandler(void) {
if (IS_MAIN_THREAD)
return (&htmlDefaultSAXHandler);
else
return (&get_glob_struct()->htmlDefaultSAXHandler);
}
extern int oldXMLWDcompatibility;
#undef oldXMLWDcompatibility
int *
__oldXMLWDcompatibility(void) {
if (IS_MAIN_THREAD)
return (&oldXMLWDcompatibility);
else
return (&get_glob_struct()->oldXMLWDcompatibility);
}
extern xmlBufferAllocationScheme xmlBufferAllocScheme;
#undef xmlBufferAllocScheme
xmlBufferAllocationScheme *
__xmlBufferAllocScheme(void) {
if (IS_MAIN_THREAD)
return (&xmlBufferAllocScheme);
else
return (&get_glob_struct()->xmlBufferAllocScheme);
}
extern int xmlDefaultBufferSize;
#undef xmlDefaultBufferSize
int *
__xmlDefaultBufferSize(void) {
if (IS_MAIN_THREAD)
return (&xmlDefaultBufferSize);
else
return (&get_glob_struct()->xmlDefaultBufferSize);
}
extern xmlSAXHandler xmlDefaultSAXHandler;
#undef xmlDefaultSAXHandler
xmlSAXHandler *
__xmlDefaultSAXHandler(void) {
if (IS_MAIN_THREAD)
return (&xmlDefaultSAXHandler);
else
return (&get_glob_struct()->xmlDefaultSAXHandler);
}
extern xmlSAXLocator xmlDefaultSAXLocator;
#undef xmlDefaultSAXLocator
xmlSAXLocator *
__xmlDefaultSAXLocator(void) {
if (IS_MAIN_THREAD)
return (&xmlDefaultSAXLocator);
else
return (&get_glob_struct()->xmlDefaultSAXLocator);
}
extern int xmlDoValidityCheckingDefaultValue;
#undef xmlDoValidityCheckingDefaultValue
int *
__xmlDoValidityCheckingDefaultValue(void) {
if (IS_MAIN_THREAD)
return (&xmlDoValidityCheckingDefaultValue);
else
return (&get_glob_struct()->xmlDoValidityCheckingDefaultValue);
}
extern xmlFreeFunc xmlFree;
#undef xmlFree
xmlFreeFunc *
__xmlFree(void) {
if (IS_MAIN_THREAD)
return (&xmlFree);
else
return (&get_glob_struct()->xmlFree);
}
extern xmlGenericErrorFunc xmlGenericError;
#undef xmlGenericError
xmlGenericErrorFunc *
__xmlGenericError(void) {
if (IS_MAIN_THREAD)
return (&xmlGenericError);
else
return (&get_glob_struct()->xmlGenericError);
}
extern void * xmlGenericErrorContext;
#undef xmlGenericErrorContext
void * *
__xmlGenericErrorContext(void) {
if (IS_MAIN_THREAD)
return (&xmlGenericErrorContext);
else
return (&get_glob_struct()->xmlGenericErrorContext);
}
extern int xmlGetWarningsDefaultValue;
#undef xmlGetWarningsDefaultValue
int *
__xmlGetWarningsDefaultValue(void) {
if (IS_MAIN_THREAD)
return (&xmlGetWarningsDefaultValue);
else
return (&get_glob_struct()->xmlGetWarningsDefaultValue);
}
extern int xmlIndentTreeOutput;
#undef xmlIndentTreeOutput
int *
__xmlIndentTreeOutput(void) {
if (IS_MAIN_THREAD)
return (&xmlIndentTreeOutput);
else
return (&get_glob_struct()->xmlIndentTreeOutput);
}
extern int xmlKeepBlanksDefaultValue;
#undef xmlKeepBlanksDefaultValue
int *
__xmlKeepBlanksDefaultValue(void) {
if (IS_MAIN_THREAD)
return (&xmlKeepBlanksDefaultValue);
else
return (&get_glob_struct()->xmlKeepBlanksDefaultValue);
}
extern int xmlLineNumbersDefaultValue;
#undef xmlLineNumbersDefaultValue
int *
__xmlLineNumbersDefaultValue(void) {
if (IS_MAIN_THREAD)
return (&xmlLineNumbersDefaultValue);
else
return (&get_glob_struct()->xmlLineNumbersDefaultValue);
}
extern int xmlLoadExtDtdDefaultValue;
#undef xmlLoadExtDtdDefaultValue
int *
__xmlLoadExtDtdDefaultValue(void) {
if (IS_MAIN_THREAD)
return (&xmlLoadExtDtdDefaultValue);
else
return (&get_glob_struct()->xmlLoadExtDtdDefaultValue);
}
extern xmlMallocFunc xmlMalloc;
#undef xmlMalloc
xmlMallocFunc *
__xmlMalloc(void) {
if (IS_MAIN_THREAD)
return (&xmlMalloc);
else
return (&get_glob_struct()->xmlMalloc);
}
extern xmlStrdupFunc xmlMemStrdup;
#undef xmlMemStrdup
xmlStrdupFunc *
__xmlMemStrdup(void) {
if (IS_MAIN_THREAD)
return (&xmlMemStrdup);
else
return (&get_glob_struct()->xmlMemStrdup);
}
extern int xmlParserDebugEntities;
#undef xmlParserDebugEntities
int *
__xmlParserDebugEntities(void) {
if (IS_MAIN_THREAD)
return (&xmlParserDebugEntities);
else
return (&get_glob_struct()->xmlParserDebugEntities);
}
extern const char * xmlParserVersion;
#undef xmlParserVersion
const char * *
__xmlParserVersion(void) {
if (IS_MAIN_THREAD)
return (&xmlParserVersion);
else
return (&get_glob_struct()->xmlParserVersion);
}
extern int xmlPedanticParserDefaultValue;
#undef xmlPedanticParserDefaultValue
int *
__xmlPedanticParserDefaultValue(void) {
if (IS_MAIN_THREAD)
return (&xmlPedanticParserDefaultValue);
else
return (&get_glob_struct()->xmlPedanticParserDefaultValue);
}
extern xmlReallocFunc xmlRealloc;
#undef xmlRealloc
xmlReallocFunc *
__xmlRealloc(void) {
if (IS_MAIN_THREAD)
return (&xmlRealloc);
else
return (&get_glob_struct()->xmlRealloc);
}
extern int xmlSaveNoEmptyTags;
#undef xmlSaveNoEmptyTags
int *
__xmlSaveNoEmptyTags(void) {
if (IS_MAIN_THREAD)
return (&xmlSaveNoEmptyTags);
else
return (&get_glob_struct()->xmlSaveNoEmptyTags);
}
extern int xmlSubstituteEntitiesDefaultValue;
#undef xmlSubstituteEntitiesDefaultValue
int *
__xmlSubstituteEntitiesDefaultValue(void) {
if (IS_MAIN_THREAD)
return (&xmlSubstituteEntitiesDefaultValue);
else
return (&get_glob_struct()->xmlSubstituteEntitiesDefaultValue);
}

View File

@ -29,7 +29,8 @@ xmlinc_HEADERS = \
xmlversion.h \
xmlwin32version.h \
DOCBparser.h \
catalog.h
catalog.h \
threads.h
install-exec-hook:
$(mkinstalldirs) $(DESTDIR)$(xmlincdir)

294
include/libxml/globals.h Normal file
View File

@ -0,0 +1,294 @@
/*
* globals.h: interface for all global variables of the library
*
* The bottom of this file is automatically generated by build_glob.py
* based on the description file global.data
*
* See Copyright for the status of this software.
*
* Gary Pennington <Gary.Pennington@uk.sun.com>
* daniel@veillard.com
*/
#ifndef __XML_GLOBALS_H
#define __XML_GLOBALS_H
#include <libxml/parser.h>
#include <libxml/xmlerror.h>
#include <libxml/SAX.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Externally global symbols which need to be protected for backwards
* compatibility support.
*/
#undef docbDefaultSAXHandler
#undef htmlDefaultSAXHandler
#undef oldXMLWDcompatibility
#undef xmlBufferAllocScheme
#undef xmlDefaultBufferSize
#undef xmlDefaultSAXHandler
#undef xmlDefaultSAXLocator
#undef xmlDoValidityCheckingDefaultValue
#undef xmlFree
#undef xmlGenericError
#undef xmlGenericErrorContext
#undef xmlGetWarningsDefaultValue
#undef xmlIndentTreeOutput
#undef xmlKeepBlanksDefaultValue
#undef xmlLineNumbersDefaultValue
#undef xmlLoadExtDtdDefaultValue
#undef xmlMalloc
#undef xmlMemStrdup
#undef xmlParserDebugEntities
#undef xmlParserVersion
#undef xmlPedanticParserDefaultValue
#undef xmlRealloc
#undef xmlSaveNoEmptyTags
/* #undef xmlStringComment */
/* #undef xmlStringText */
/* #undef xmlStringTextNoenc */
#undef xmlSubstituteEntitiesDefaultValue
typedef struct _xmlGlobalState xmlGlobalState;
typedef xmlGlobalState *xmlGlobalStatePtr;
struct _xmlGlobalState
{
xmlSAXHandler docbDefaultSAXHandler;
xmlSAXHandler htmlDefaultSAXHandler;
int oldXMLWDcompatibility;
xmlBufferAllocationScheme xmlBufferAllocScheme;
int xmlDefaultBufferSize;
xmlSAXHandler xmlDefaultSAXHandler;
xmlSAXLocator xmlDefaultSAXLocator;
int xmlDoValidityCheckingDefaultValue;
xmlFreeFunc xmlFree;
xmlGenericErrorFunc xmlGenericError;
void *xmlGenericErrorContext;
int xmlGetWarningsDefaultValue;
int xmlIndentTreeOutput;
int xmlKeepBlanksDefaultValue;
int xmlLineNumbersDefaultValue;
int xmlLoadExtDtdDefaultValue;
xmlMallocFunc xmlMalloc;
xmlStrdupFunc xmlMemStrdup;
int xmlParserDebugEntities;
const char *xmlParserVersion;
int xmlPedanticParserDefaultValue;
xmlReallocFunc xmlRealloc;
int xmlSaveNoEmptyTags;
/* const xmlChar xmlStringComment[8]; */
/* const xmlChar xmlStringText[5]; */
/* const xmlChar xmlStringTextNoenc[10]; */
int xmlSubstituteEntitiesDefaultValue;
};
void xmlInitializeGlobalState(xmlGlobalStatePtr gs);
/*
* Everything starting from the line below is
* Automatically generated by build_glob.py.
* Do not modify the previous line.
*/
#ifdef LIBXML_THREAD_ENABLED
extern xmlSAXHandler *__docbDefaultSAXHandler(void);
#define docbDefaultSAXHandler \
(*(__docbDefaultSAXHandler()))
#else
extern xmlSAXHandler docbDefaultSAXHandler;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern xmlSAXHandler *__htmlDefaultSAXHandler(void);
#define htmlDefaultSAXHandler \
(*(__htmlDefaultSAXHandler()))
#else
extern xmlSAXHandler htmlDefaultSAXHandler;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__oldXMLWDcompatibility(void);
#define oldXMLWDcompatibility \
(*(__oldXMLWDcompatibility()))
#else
extern int oldXMLWDcompatibility;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern xmlBufferAllocationScheme *__xmlBufferAllocScheme(void);
#define xmlBufferAllocScheme \
(*(__xmlBufferAllocScheme()))
#else
extern xmlBufferAllocationScheme xmlBufferAllocScheme;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlDefaultBufferSize(void);
#define xmlDefaultBufferSize \
(*(__xmlDefaultBufferSize()))
#else
extern int xmlDefaultBufferSize;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern xmlSAXHandler *__xmlDefaultSAXHandler(void);
#define xmlDefaultSAXHandler \
(*(__xmlDefaultSAXHandler()))
#else
extern xmlSAXHandler xmlDefaultSAXHandler;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern xmlSAXLocator *__xmlDefaultSAXLocator(void);
#define xmlDefaultSAXLocator \
(*(__xmlDefaultSAXLocator()))
#else
extern xmlSAXLocator xmlDefaultSAXLocator;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlDoValidityCheckingDefaultValue(void);
#define xmlDoValidityCheckingDefaultValue \
(*(__xmlDoValidityCheckingDefaultValue()))
#else
extern int xmlDoValidityCheckingDefaultValue;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern xmlFreeFunc *__xmlFree(void);
#define xmlFree \
(*(__xmlFree()))
#else
extern xmlFreeFunc xmlFree;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern xmlGenericErrorFunc *__xmlGenericError(void);
#define xmlGenericError \
(*(__xmlGenericError()))
#else
extern xmlGenericErrorFunc xmlGenericError;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern void * *__xmlGenericErrorContext(void);
#define xmlGenericErrorContext \
(*(__xmlGenericErrorContext()))
#else
extern void * xmlGenericErrorContext;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlGetWarningsDefaultValue(void);
#define xmlGetWarningsDefaultValue \
(*(__xmlGetWarningsDefaultValue()))
#else
extern int xmlGetWarningsDefaultValue;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlIndentTreeOutput(void);
#define xmlIndentTreeOutput \
(*(__xmlIndentTreeOutput()))
#else
extern int xmlIndentTreeOutput;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlKeepBlanksDefaultValue(void);
#define xmlKeepBlanksDefaultValue \
(*(__xmlKeepBlanksDefaultValue()))
#else
extern int xmlKeepBlanksDefaultValue;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlLineNumbersDefaultValue(void);
#define xmlLineNumbersDefaultValue \
(*(__xmlLineNumbersDefaultValue()))
#else
extern int xmlLineNumbersDefaultValue;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlLoadExtDtdDefaultValue(void);
#define xmlLoadExtDtdDefaultValue \
(*(__xmlLoadExtDtdDefaultValue()))
#else
extern int xmlLoadExtDtdDefaultValue;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern xmlMallocFunc *__xmlMalloc(void);
#define xmlMalloc \
(*(__xmlMalloc()))
#else
extern xmlMallocFunc xmlMalloc;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern xmlStrdupFunc *__xmlMemStrdup(void);
#define xmlMemStrdup \
(*(__xmlMemStrdup()))
#else
extern xmlStrdupFunc xmlMemStrdup;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlParserDebugEntities(void);
#define xmlParserDebugEntities \
(*(__xmlParserDebugEntities()))
#else
extern int xmlParserDebugEntities;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern const char * *__xmlParserVersion(void);
#define xmlParserVersion \
(*(__xmlParserVersion()))
#else
extern const char * xmlParserVersion;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlPedanticParserDefaultValue(void);
#define xmlPedanticParserDefaultValue \
(*(__xmlPedanticParserDefaultValue()))
#else
extern int xmlPedanticParserDefaultValue;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern xmlReallocFunc *__xmlRealloc(void);
#define xmlRealloc \
(*(__xmlRealloc()))
#else
extern xmlReallocFunc xmlRealloc;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlSaveNoEmptyTags(void);
#define xmlSaveNoEmptyTags \
(*(__xmlSaveNoEmptyTags()))
#else
extern int xmlSaveNoEmptyTags;
#endif
#ifdef LIBXML_THREAD_ENABLED
extern int *__xmlSubstituteEntitiesDefaultValue(void);
#define xmlSubstituteEntitiesDefaultValue \
(*(__xmlSubstituteEntitiesDefaultValue()))
#else
extern int xmlSubstituteEntitiesDefaultValue;
#endif
#ifdef __cplusplus
}
#endif
#endif /* __XML_GLOBALS_H */

54
include/libxml/threads.h Normal file
View File

@ -0,0 +1,54 @@
/**
* threads.c: set of generic threading related routines
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#ifndef __XML_THREADS_H__
#define __XML_THREADS_H__
#include <libxml/globals.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* xmlMutex are a simple mutual exception locks
*/
typedef struct _xmlMutex xmlMutex;
typedef xmlMutex *xmlMutexPtr;
xmlMutexPtr xmlNewMutex (void);
void xmlMutexLock (xmlMutexPtr tok);
void xmlMutexUnlock (xmlMutexPtr tok);
void xmlFreeMutex (xmlMutexPtr tok);
/*
* xmlRMutex are reentrant mutual exception locks
*/
typedef struct _xmlRMutex xmlRMutex;
typedef xmlRMutex *xmlRMutexPtr;
xmlRMutexPtr xmlNewRMutex (void);
void xmlRMutexLock (xmlRMutexPtr tok);
void xmlRMutexUnlock (xmlRMutexPtr tok);
void xmlFreeRMutex (xmlRMutexPtr tok);
/*
* Library wide APIs
*/
void xmlInitThreads (void);
void xmlLockLibrary (void);
void xmlUnlockLibrary(void);
void xmlCleanupThreads(void);
xmlGlobalStatePtr xmlGetGlobalState(void);
#ifdef __cplusplus
}
#endif
#endif /* __XML_THREADS_H__ */

View File

@ -66,6 +66,17 @@ extern void xmlCheckVersion(int version);
#define WITHOUT_TRIO
#endif
/**
* LIBXML_THREADS_ENABLED:
*
* Whether the thread support is configured in
*/
#if @WITH_THREADS@
#if defined(_REENTRANT) || (_POSIX_C_SOURCE - 0 >= 199506L)
#define LIBXML_THREAD_ENABLED
#endif
#endif
/**
* LIBXML_FTP_ENABLED:
*

372
threads.c Normal file
View File

@ -0,0 +1,372 @@
/**
* threads.c: set of generic threading related routines
*
* See Copyright for the status of this software.
*
* Gary Pennington <Gary.Pennington@uk.sun.com>
* daniel@veillard.com
*/
#include "libxml.h"
#include <string.h>
#include <libxml/threads.h>
#include <libxml/globals.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#if defined(SOLARIS)
#include <note.h>
#endif
/*
* TODO: this module still uses malloc/free and not xmlMalloc/xmlFree
* to avoid some crazyness since xmlMalloc/xmlFree may actually
* be hosted on allocated blocks needing them for the allocation ...
*/
/*
* xmlMutex are a simple mutual exception locks
*/
struct _xmlMutex {
#ifdef HAVE_PTHREAD_H
pthread_mutex_t lock;
#else
int empty;
#endif
};
/*
* xmlRMutex are reentrant mutual exception locks
*/
struct _xmlRMutex {
#ifdef HAVE_PTHREAD_H
pthread_mutex_t lock;
unsigned int held;
unsigned int waiters;
pthread_t tid;
pthread_cond_t cv;
#else
int empty;
#endif
};
/*
* This module still has some internal static data.
* - xmlLibraryLock a global lock
* - globalkey used for per-thread data
* - keylock protecting globalkey
* - keyonce to mark initialization of globalkey
*/
#ifdef HAVE_PTHREAD_H
static pthread_mutex_t keylock;
static pthread_key_t globalkey;
static int keyonce = 0;
#endif
static xmlRMutexPtr xmlLibraryLock = NULL;
#if defined(SOLARIS)
NOTE(DATA_READABLE_WITHOUT_LOCK(keyonce))
#endif
/**
* xmlMutexPtr:
*
* xmlNewMutex() is used to allocate a libxml2 token struct for use in
* synchronizing access to data.
*
* Returns a new simple mutex pointer or NULL in case of error
*/
xmlMutexPtr
xmlNewMutex(void)
{
xmlMutexPtr tok;
if ((tok = malloc(sizeof(xmlMutex))) == NULL)
return (NULL);
#ifdef HAVE_PTHREAD_H
pthread_mutex_init(&tok->lock, NULL);
#endif
return (tok);
}
/**
* xmlFreeMutex:
* @tok: the simple mutex
*
* xmlFreeMutex() is used to reclaim resources associated with a libxml2 token
* struct.
*/
void
xmlFreeMutex(xmlMutexPtr tok)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_destroy(&tok->lock);
#endif
free(tok);
}
/**
* xmlMutexLock:
* @tok: the simple mutex
*
* xmlMutexLock() is used to lock a libxml2 token.
*/
void
xmlMutexLock(xmlMutexPtr tok)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_lock(&tok->lock);
#endif
}
/**
* xmlMutexUnlock:
* @tok: the simple mutex
*
* xmlMutexUnlock() is used to unlock a libxml2 token.
*/
void
xmlMutexUnlock(xmlMutexPtr tok)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_unlock(&tok->lock);
#endif
}
/**
* xmlRNewMutex:
*
* xmlRNewMutex() is used to allocate a reentrant mutex for use in
* synchronizing access to data. token_r is a re-entrant lock and thus useful
* for synchronizing access to data structures that may be manipulated in a
* recursive fashion.
*
* Returns the new reentrant mutex pointer or NULL in case of error
*/
xmlRMutexPtr
xmlNewRMutex(void)
{
xmlRMutexPtr tok;
if ((tok = malloc(sizeof(xmlRMutex))) == NULL)
return (NULL);
#ifdef HAVE_PTHREAD_H
pthread_mutex_init(&tok->lock, NULL);
tok->held = 0;
tok->waiters = 0;
#endif
return (tok);
}
/**
* xmlRFreeMutex:
* @tok: the reentrant mutex
*
* xmlRFreeMutex() is used to reclaim resources associated with a
* reentrant mutex.
*/
void
xmlFreeRMutex(xmlRMutexPtr tok)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_destroy(&tok->lock);
#endif
free(tok);
}
/**
* xmlRMutexLock:
* @tok: the reentrant mutex
*
* xmlRMutexLock() is used to lock a libxml2 token_r.
*/
void
xmlRMutexLock(xmlRMutexPtr tok)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_lock(&tok->lock);
if (tok->held) {
if (pthread_equal(tok->tid, pthread_self())) {
tok->held++;
pthread_mutex_unlock(&tok->lock);
return;
} else {
tok->waiters++;
while (tok->held)
pthread_cond_wait(&tok->cv, &tok->lock);
tok->waiters--;
}
}
tok->tid = pthread_self();
tok->held = 1;
pthread_mutex_unlock(&tok->lock);
#endif
}
/**
* xmlRMutexUnlock:
* @tok: the reentrant mutex
*
* xmlRMutexUnlock() is used to unlock a libxml2 token_r.
*/
void
xmlRMutexUnlock(xmlRMutexPtr tok)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_lock(&tok->lock);
tok->held--;
if (tok->held == 0) {
if (tok->waiters)
pthread_cond_signal(&tok->cv);
tok->tid = 0;
}
pthread_mutex_unlock(&tok->lock);
#endif
}
/************************************************************************
* *
* Per thread global state handling *
* *
************************************************************************/
/**
* xmlFreeGlobalState:
* @state: a thread global state
*
* xmlFreeGlobalState() is called when a thread terminates with a non-NULL
* global state. It is is used here to reclaim memory resources.
*/
static void
xmlFreeGlobalState(void *state)
{
free(state);
}
/**
* xmlNewGlobalState:
*
* xmlNewGlobalState() allocates a global state. This structure is used to
* hold all data for use by a thread when supporting backwards compatibility
* of libmxml2 to pre-thread-safe behaviour.
*
* Returns the newly allocated xmlGlobalStatePtr or NULL in case of error
*/
static xmlGlobalStatePtr
xmlNewGlobalState(void)
{
xmlGlobalState *gs;
gs = malloc(sizeof(xmlGlobalState));
if (gs == NULL)
return(NULL);
memset(gs, 0, sizeof(gs));
xmlInitializeGlobalState(gs);
return (gs);
}
/**
* xmlGetGlobalState:
*
* xmlGetGlobalState() is called to retrieve the global state for a thread.
* keyonce will only be set once during a library invocation and is used
* to create globalkey, the key used to store each thread's TSD.
*
* Note: it should not be called for the "main" thread as this thread uses
* the existing global variables defined in the library.
*
* Returns the thread global state or NULL in case of error
*/
xmlGlobalStatePtr
xmlGetGlobalState(void)
{
#ifdef HAVE_PTHREAD_H
xmlGlobalState *globalval;
if (keyonce == 0) {
(void) pthread_mutex_lock(&keylock);
if (keyonce == 0) {
keyonce++;
(void) pthread_key_create(&globalkey, xmlFreeGlobalState);
}
(void) pthread_mutex_unlock(&keylock);
}
if ((globalval = (xmlGlobalState *)
pthread_getspecific(globalkey)) == NULL) {
xmlGlobalState *tsd = xmlNewGlobalState();
pthread_setspecific(globalkey, tsd);
return (tsd);
} else
return (globalval);
#endif
}
/************************************************************************
* *
* Library wide thread interfaces *
* *
************************************************************************/
/**
* xmlLockLibrary:
*
* xmlLockLibrary() is used to take out a re-entrant lock on the libxml2
* library.
*/
void
xmlLockLibrary(void)
{
xmlRMutexLock(xmlLibraryLock);
}
/**
* xmlUnlockLibrary:
*
* xmlUnlockLibrary() is used to release a re-entrant lock on the libxml2
* library.
*/
void
xmlUnlockLibrary(void)
{
xmlRMutexUnlock(xmlLibraryLock);
}
/**
* xmlInitThreads:
*
* xmlInitThreads() is used to to initialize all the thread related
* data of the libxml2 library.
*/
void
xmlInitThreads(void)
{
}
/**
* xmlCleanupThreads:
*
* xmlCleanupThreads() is used to to cleanup all the thread related
* data of the libxml2 library once processing has ended.
*/
void
xmlCleanupThreads(void)
{
}

View File

@ -370,9 +370,11 @@ int main(int argc, char **argv) {
} else if (argv[i][0] == '-')
continue;
filename = argv[i];
/* !!!!!!!!!!!!!!!!!! TODO !!!!
if (sgml)
ret = xmlLoadSGMLSuperCatalog(argv[i]);
else
!!!!!!!!! */
ret = xmlLoadCatalog(argv[i]);
if ((!sgml) && (ret < 0) && (create)) {
xmlCatalogAdd(BAD_CAST "catalog", BAD_CAST argv[i], NULL);