From dbfe05aff4d242e31fcd7621a4901a6fa10b988e Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Wed, 4 May 2005 09:18:00 +0000 Subject: [PATCH] on linux/gcc use weak definitions to avoid linking with pthread library on * Makefile.am configure.in threads.c: on linux/gcc use weak definitions to avoid linking with pthread library on non-threaded environments. * xpath.c: applied patch from Mark Vakoc w.r.t. a buggy namespace list allocation. Daniel --- ChangeLog | 7 ++++ Makefile.am | 2 +- configure.in | 8 ++++ threads.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++----- xpath.c | 2 +- 5 files changed, 113 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index c94e972c..6137b571 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Wed May 4 11:16:00 CEST 2005 Daniel Veillard + + * Makefile.am configure.in threads.c: on linux/gcc use weak definitions + to avoid linking with pthread library on non-threaded environments. + * xpath.c: applied patch from Mark Vakoc w.r.t. a buggy namespace + list allocation. + Fri Apr 29 11:27:37 CEST 2005 Kasimier Buchcik * parser.c: Fixed a test for duplicate attributes: Non-prefixed diff --git a/Makefile.am b/Makefile.am index 63ad9048..8c0fdfe0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -82,7 +82,7 @@ testC14N_LDADD= $(LDADDS) testThreads_SOURCES=testThreads@THREADS_W32@.c testThreads_LDFLAGS = testThreads_DEPENDENCIES = $(DEPS) -testThreads_LDADD= $(LDADDS) +testThreads_LDADD= @BASE_THREAD_LIBS@ $(LDADDS) testURI_SOURCES=testURI.c testURI_LDFLAGS = diff --git a/configure.in b/configure.in index d9dfb033..9ef667dd 100644 --- a/configure.in +++ b/configure.in @@ -719,6 +719,7 @@ dnl dnl Thread-related stuff dnl THREAD_LIBS="" +BASE_THREAD_LIBS="" WITH_THREADS=0 THREAD_CFLAGS="" TEST_THREADS="" @@ -745,6 +746,12 @@ else *beos*) WITH_THREADS="1" THREAD_CFLAGS="$THREAD_CFLAGS -DHAVE_BEOS_THREADS" ;; + *linux*) + if test "${CC}" = "gcc" -a "${THREAD_LIBS}" = "-lpthread" ; then + THREAD_LIBS="" + BASE_THREAD_LIBS="-lpthread" + fi + ;; esac if test "$WITH_THREADS" = "1" ; then THREAD_CFLAGS="$THREAD_CFLAGS -D_REENTRANT" @@ -756,6 +763,7 @@ if test "$with_thread_alloc" = "yes" -a "$WITH_THREADS" = "1" ; then fi AC_SUBST(THREAD_LIBS) +AC_SUBST(BASE_THREAD_LIBS) AC_SUBST(WITH_THREADS) AC_SUBST(THREAD_CFLAGS) AC_SUBST(TEST_THREADS) diff --git a/threads.c b/threads.c index 6066a276..8b423458 100644 --- a/threads.c +++ b/threads.c @@ -46,6 +46,46 @@ /* #define DEBUG_THREADS */ +#ifdef HAVE_PTHREAD_H + +static int libxml_is_threaded = -1; +#ifdef __GNUC__ +#ifdef linux +#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3) +extern int pthread_once (pthread_once_t *__once_control, + void (*__init_routine) (void)) + __attribute((weak)); +extern void *pthread_getspecific (pthread_key_t __key) + __attribute((weak)); +extern int pthread_setspecific (pthread_key_t __key, + __const void *__pointer) + __attribute((weak)); +extern int pthread_key_create (pthread_key_t *__key, + void (*__destr_function) (void *)) + __attribute((weak)); +extern int pthread_mutex_init () + __attribute((weak)); +extern int pthread_mutex_destroy () + __attribute((weak)); +extern int pthread_mutex_lock () + __attribute((weak)); +extern int pthread_mutex_unlock () + __attribute((weak)); +extern int pthread_cond_init () + __attribute((weak)); +extern int pthread_equal () + __attribute((weak)); +extern pthread_t pthread_self () + __attribute((weak)); +extern int pthread_key_create () + __attribute((weak)); +extern int pthread_cond_signal () + __attribute((weak)); +#endif +#endif /* linux */ +#endif /* __GNUC__ */ +#endif /* HAVE_PTHREAD_H */ + /* * TODO: this module still uses malloc/free and not xmlMalloc/xmlFree * to avoid some crazyness since xmlMalloc/xmlFree may actually @@ -140,7 +180,8 @@ xmlNewMutex(void) if ((tok = malloc(sizeof(xmlMutex))) == NULL) return (NULL); #ifdef HAVE_PTHREAD_H - pthread_mutex_init(&tok->lock, NULL); + if (libxml_is_threaded != 0) + pthread_mutex_init(&tok->lock, NULL); #elif defined HAVE_WIN32_THREADS tok->mutex = CreateMutex(NULL, FALSE, NULL); #elif defined HAVE_BEOS_THREADS @@ -166,7 +207,8 @@ xmlFreeMutex(xmlMutexPtr tok) if (tok == NULL) return; #ifdef HAVE_PTHREAD_H - pthread_mutex_destroy(&tok->lock); + if (libxml_is_threaded != 0) + pthread_mutex_destroy(&tok->lock); #elif defined HAVE_WIN32_THREADS CloseHandle(tok->mutex); #elif defined HAVE_BEOS_THREADS @@ -187,7 +229,8 @@ xmlMutexLock(xmlMutexPtr tok) if (tok == NULL) return; #ifdef HAVE_PTHREAD_H - pthread_mutex_lock(&tok->lock); + if (libxml_is_threaded != 0) + pthread_mutex_lock(&tok->lock); #elif defined HAVE_WIN32_THREADS WaitForSingleObject(tok->mutex, INFINITE); #elif defined HAVE_BEOS_THREADS @@ -214,7 +257,8 @@ xmlMutexUnlock(xmlMutexPtr tok) if (tok == NULL) return; #ifdef HAVE_PTHREAD_H - pthread_mutex_unlock(&tok->lock); + if (libxml_is_threaded != 0) + pthread_mutex_unlock(&tok->lock); #elif defined HAVE_WIN32_THREADS ReleaseMutex(tok->mutex); #elif defined HAVE_BEOS_THREADS @@ -243,10 +287,12 @@ xmlNewRMutex(void) if ((tok = malloc(sizeof(xmlRMutex))) == NULL) return (NULL); #ifdef HAVE_PTHREAD_H - pthread_mutex_init(&tok->lock, NULL); - tok->held = 0; - tok->waiters = 0; - pthread_cond_init(&tok->cv, NULL); + if (libxml_is_threaded != 0) { + pthread_mutex_init(&tok->lock, NULL); + tok->held = 0; + tok->waiters = 0; + pthread_cond_init(&tok->cv, NULL); + } #elif defined HAVE_WIN32_THREADS InitializeCriticalSection(&tok->cs); tok->count = 0; @@ -270,8 +316,11 @@ xmlNewRMutex(void) void xmlFreeRMutex(xmlRMutexPtr tok ATTRIBUTE_UNUSED) { + if (tok == NULL) + return; #ifdef HAVE_PTHREAD_H - pthread_mutex_destroy(&tok->lock); + if (libxml_is_threaded != 0) + pthread_mutex_destroy(&tok->lock); #elif defined HAVE_WIN32_THREADS DeleteCriticalSection(&tok->cs); #elif defined HAVE_BEOS_THREADS @@ -292,6 +341,9 @@ xmlRMutexLock(xmlRMutexPtr tok) if (tok == NULL) return; #ifdef HAVE_PTHREAD_H + if (libxml_is_threaded == 0) + return; + pthread_mutex_lock(&tok->lock); if (tok->held) { if (pthread_equal(tok->tid, pthread_self())) { @@ -334,6 +386,9 @@ xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED) if (tok == NULL) return; #ifdef HAVE_PTHREAD_H + if (libxml_is_threaded == 0) + return; + pthread_mutex_lock(&tok->lock); tok->held--; if (tok->held == 0) { @@ -470,6 +525,9 @@ xmlGetGlobalState(void) #ifdef HAVE_PTHREAD_H xmlGlobalState *globalval; + if (libxml_is_threaded == 0) + return(NULL); + pthread_once(&once_control, xmlOnceInit); if ((globalval = (xmlGlobalState *) @@ -559,6 +617,8 @@ int xmlGetThreadId(void) { #ifdef HAVE_PTHREAD_H + if (libxml_is_threaded == 0) + return(0); return((int) pthread_self()); #elif defined HAVE_WIN32_THREADS return GetCurrentThreadId(); @@ -580,6 +640,10 @@ int xmlIsMainThread(void) { #ifdef HAVE_PTHREAD_H + if (libxml_is_threaded == -1) + xmlInitThreads(); + if (libxml_is_threaded == 0) + return(1); pthread_once(&once_control, xmlOnceInit); #elif defined HAVE_WIN32_THREADS xmlOnceInit (); @@ -646,6 +710,29 @@ xmlInitThreads(void) #if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) InitializeCriticalSection(&cleanup_helpers_cs); #endif +#ifdef HAVE_PTHREAD_H + if (libxml_is_threaded == -1) { + if ((pthread_once != NULL) && + (pthread_getspecific != NULL) && + (pthread_setspecific != NULL) && + (pthread_key_create != NULL) && + (pthread_mutex_init != NULL) && + (pthread_mutex_destroy != NULL) && + (pthread_mutex_lock != NULL) && + (pthread_mutex_unlock != NULL) && + (pthread_cond_init != NULL) && + (pthread_equal != NULL) && + (pthread_self != NULL) && + (pthread_key_create != NULL) && + (pthread_cond_signal != NULL)) { + libxml_is_threaded = 1; +/* fprintf(stderr, "Running multithreaded\n"); */ + } else { +/* fprintf(stderr, "Running without multithread\n"); */ + libxml_is_threaded = 0; + } + } +#endif } /** diff --git a/xpath.c b/xpath.c index c24c3132..862ff535 100644 --- a/xpath.c +++ b/xpath.c @@ -11300,7 +11300,7 @@ xmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { if (ctxt != NULL) { dict = ctxt->dict; if (ctxt->nsNr > 0) { - namespaces = xmlMalloc(2 * (ctxt->nsNr + 1)); + namespaces = xmlMalloc(2 * (ctxt->nsNr + 1) * sizeof(xmlChar*)); if (namespaces == NULL) { xmlXPathErrMemory(ctxt, "allocating namespaces array\n"); return(NULL);