| Index: third_party/libxml/threads.c
|
| diff --git a/third_party/libxml/threads.c b/third_party/libxml/threads.c
|
| index 6481b403e69e136391911d6e3a21ac1d5bb2ae11..98fd2c23f2e8b676030ff5f1a28e585e55f31e00 100644
|
| --- a/third_party/libxml/threads.c
|
| +++ b/third_party/libxml/threads.c
|
| @@ -1,5 +1,5 @@
|
| /**
|
| - * threads.c: set of generic threading related routines
|
| + * threads.c: set of generic threading related routines
|
| *
|
| * See Copyright for the status of this software.
|
| *
|
| @@ -26,9 +26,7 @@
|
| #endif
|
| #ifdef HAVE_PTHREAD_H
|
| #include <pthread.h>
|
| -#endif
|
| -
|
| -#ifdef HAVE_WIN32_THREADS
|
| +#elif defined HAVE_WIN32_THREADS
|
| #include <windows.h>
|
| #ifndef HAVE_COMPILER_TLS
|
| #include <process.h>
|
| @@ -63,6 +61,8 @@ extern int pthread_setspecific (pthread_key_t __key,
|
| extern int pthread_key_create (pthread_key_t *__key,
|
| void (*__destr_function) (void *))
|
| __attribute((weak));
|
| +extern int pthread_key_delete (pthread_key_t __key)
|
| + __attribute((weak));
|
| extern int pthread_mutex_init ()
|
| __attribute((weak));
|
| extern int pthread_mutex_destroy ()
|
| @@ -73,12 +73,18 @@ extern int pthread_mutex_unlock ()
|
| __attribute((weak));
|
| extern int pthread_cond_init ()
|
| __attribute((weak));
|
| +extern int pthread_cond_destroy ()
|
| + __attribute((weak));
|
| +extern int pthread_cond_wait ()
|
| + __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_key_delete ()
|
| + __attribute((weak));
|
| extern int pthread_cond_signal ()
|
| __attribute((weak));
|
| #endif
|
| @@ -404,7 +410,7 @@ xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
|
| if (tok->held == 0) {
|
| if (tok->waiters)
|
| pthread_cond_signal(&tok->cv);
|
| - tok->tid = 0;
|
| + memset(&tok->tid, 0, sizeof(tok->tid));
|
| }
|
| pthread_mutex_unlock(&tok->lock);
|
| #elif defined HAVE_WIN32_THREADS
|
| @@ -521,7 +527,8 @@ __xmlGlobalInitMutexUnlock(void)
|
| void
|
| __xmlGlobalInitMutexDestroy(void)
|
| {
|
| -#if defined HAVE_WIN32_THREADS
|
| +#ifdef HAVE_PTHREAD_H
|
| +#elif defined HAVE_WIN32_THREADS
|
| if (global_init_lock != NULL) {
|
| DeleteCriticalSection(global_init_lock);
|
| free(global_init_lock);
|
| @@ -585,8 +592,8 @@ xmlNewGlobalState(void)
|
| }
|
| #endif /* LIBXML_THREAD_ENABLED */
|
|
|
| -
|
| -#ifdef HAVE_WIN32_THREADS
|
| +#ifdef HAVE_PTHREAD_H
|
| +#elif defined HAVE_WIN32_THREADS
|
| #if !defined(HAVE_COMPILER_TLS)
|
| #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
|
| typedef struct _xmlGlobalStateCleanupHelperParams {
|
| @@ -694,6 +701,7 @@ xmlGetGlobalState(void)
|
| if (p == NULL) {
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlGetGlobalState: out of memory\n");
|
| + xmlFreeGlobalState(tsd);
|
| return(NULL);
|
| }
|
| p->memory = tsd;
|
| @@ -749,6 +757,8 @@ xmlGetGlobalState(void)
|
| * xmlGetThreadId:
|
| *
|
| * xmlGetThreadId() find the current thread ID number
|
| + * Note that this is likely to be broken on some platforms using pthreads
|
| + * as the specification doesn't mandate pthread_t to be an integer type
|
| *
|
| * Returns the current thread ID number
|
| */
|
| @@ -756,9 +766,15 @@ int
|
| xmlGetThreadId(void)
|
| {
|
| #ifdef HAVE_PTHREAD_H
|
| + pthread_t id;
|
| + int ret;
|
| +
|
| if (libxml_is_threaded == 0)
|
| return (0);
|
| - return ((int) pthread_self());
|
| + id = pthread_self();
|
| + /* horrible but preserves compat, see warning above */
|
| + memcpy(&ret, &id, sizeof(ret));
|
| + return (ret);
|
| #elif defined HAVE_WIN32_THREADS
|
| return GetCurrentThreadId();
|
| #elif defined HAVE_BEOS_THREADS
|
| @@ -794,7 +810,7 @@ xmlIsMainThread(void)
|
| xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n");
|
| #endif
|
| #ifdef HAVE_PTHREAD_H
|
| - return (mainthread == pthread_self());
|
| + return (pthread_equal(mainthread,pthread_self()));
|
| #elif defined HAVE_WIN32_THREADS
|
| return (mainthread == GetCurrentThreadId());
|
| #elif defined HAVE_BEOS_THREADS
|
| @@ -843,23 +859,20 @@ xmlUnlockLibrary(void)
|
| void
|
| xmlInitThreads(void)
|
| {
|
| -#ifdef DEBUG_THREADS
|
| - xmlGenericError(xmlGenericErrorContext, "xmlInitThreads()\n");
|
| -#endif
|
| -#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_key_delete != NULL) &&
|
| (pthread_mutex_init != NULL) &&
|
| (pthread_mutex_destroy != NULL) &&
|
| (pthread_mutex_lock != NULL) &&
|
| (pthread_mutex_unlock != NULL) &&
|
| (pthread_cond_init != NULL) &&
|
| + (pthread_cond_destroy != NULL) &&
|
| + (pthread_cond_wait != NULL) &&
|
| (pthread_equal != NULL) &&
|
| (pthread_self != NULL) &&
|
| (pthread_cond_signal != NULL)) {
|
| @@ -872,6 +885,8 @@ xmlInitThreads(void)
|
| libxml_is_threaded = 0;
|
| }
|
| }
|
| +#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
|
| + InitializeCriticalSection(&cleanup_helpers_cs);
|
| #endif
|
| }
|
|
|
| @@ -880,6 +895,14 @@ xmlInitThreads(void)
|
| *
|
| * xmlCleanupThreads() is used to to cleanup all the thread related
|
| * data of the libxml2 library once processing has ended.
|
| + *
|
| + * WARNING: if your application is multithreaded or has plugin support
|
| + * calling this may crash the application if another thread or
|
| + * a plugin is still using libxml2. It's sometimes very hard to
|
| + * guess if libxml2 is in use in the application, some libraries
|
| + * or plugins may use it without notice. In case of doubt abstain
|
| + * from calling this function or do it just before calling exit()
|
| + * to avoid leak reports from valgrind !
|
| */
|
| void
|
| xmlCleanupThreads(void)
|
| @@ -887,7 +910,10 @@ xmlCleanupThreads(void)
|
| #ifdef DEBUG_THREADS
|
| xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");
|
| #endif
|
| -#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
|
| +#ifdef HAVE_PTHREAD_H
|
| + if ((libxml_is_threaded) && (pthread_key_delete != NULL))
|
| + pthread_key_delete(globalkey);
|
| +#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
|
| if (globalkey != TLS_OUT_OF_INDEXES) {
|
| xmlGlobalStateCleanupHelperParams *p;
|
|
|
| @@ -926,9 +952,7 @@ xmlOnceInit(void)
|
| #ifdef HAVE_PTHREAD_H
|
| (void) pthread_key_create(&globalkey, xmlFreeGlobalState);
|
| mainthread = pthread_self();
|
| -#endif
|
| -
|
| -#if defined(HAVE_WIN32_THREADS)
|
| +#elif defined(HAVE_WIN32_THREADS)
|
| if (!run_once.done) {
|
| if (InterlockedIncrement(&run_once.control) == 1) {
|
| #if !defined(HAVE_COMPILER_TLS)
|
| @@ -943,9 +967,7 @@ xmlOnceInit(void)
|
| Sleep(0);
|
| }
|
| }
|
| -#endif
|
| -
|
| -#ifdef HAVE_BEOS_THREADS
|
| +#elif defined HAVE_BEOS_THREADS
|
| if (atomic_add(&run_once_init, 1) == 0) {
|
| globalkey = tls_allocate();
|
| tls_set(globalkey, NULL);
|
| @@ -967,7 +989,8 @@ xmlOnceInit(void)
|
| *
|
| * Returns TRUE always
|
| */
|
| -#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
|
| +#ifdef HAVE_PTHREAD_H
|
| +#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
|
| #if defined(LIBXML_STATIC_FOR_DLL)
|
| BOOL XMLCALL
|
| xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|
|