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) |