aboutsummaryrefslogtreecommitdiff
path: root/threads.c
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@redhat.com>2013-04-05 23:10:41 +0800
committerDaniel Veillard <veillard@redhat.com>2013-04-05 23:10:41 +0800
commit5fe9e9ed1ccf217e11bd3cb99b1c6bb10cc96ba3 (patch)
tree76d1ed97820698e64365cf5182e8358fc560c0b6 /threads.c
parentbf4a8f0ea8579f05eea2e6f43df73b2a239d41b3 (diff)
downloadlibxml2-5fe9e9ed1ccf217e11bd3cb99b1c6bb10cc96ba3.tar.gz
Remove risk of lockup in dictionary initialization
Reported by Petr Sumbera <petr.sumbera@oracle.com> Two threads entering xmlInitializeDict concurently could lead to a lockup due to multiple initializations of the lock used. To avoid this problem move this to a new private function called from xmlOnceInit() and deprecate the old initalizer. Since threaded programs must call xmlInitParser() and this will lead to dereference of private data and the call to xmlOnceInit() guaranteed to be unique this should be safe now.
Diffstat (limited to 'threads.c')
-rw-r--r--threads.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/threads.c b/threads.c
index c8414e18..f2f2703c 100644
--- a/threads.c
+++ b/threads.c
@@ -954,6 +954,7 @@ xmlOnceInit(void)
#ifdef HAVE_PTHREAD_H
(void) pthread_key_create(&globalkey, xmlFreeGlobalState);
mainthread = pthread_self();
+ __xmlInitializeDict();
#elif defined(HAVE_WIN32_THREADS)
if (!run_once.done) {
if (InterlockedIncrement(&run_once.control) == 1) {
@@ -961,6 +962,7 @@ xmlOnceInit(void)
globalkey = TlsAlloc();
#endif
mainthread = GetCurrentThreadId();
+ __xmlInitializeDict();
run_once.done = 1;
} else {
/* Another thread is working; give up our slice and
@@ -974,6 +976,7 @@ xmlOnceInit(void)
globalkey = tls_allocate();
tls_set(globalkey, NULL);
mainthread = find_thread(NULL);
+ __xmlInitializeDict();
} else
atomic_add(&run_once_init, -1);
#endif