38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * threads.c: set of generic threading related routines
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * See Copyright for the status of this software.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Gary Pennington <Gary.Pennington@uk.sun.com>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * daniel@veillard.com
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define IN_LIBXML
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include "libxml.h"
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <string.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <libxml/threads.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <libxml/globals.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_SYS_TYPES_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <sys/types.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_UNISTD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <unistd.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_STDLIB_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <stdlib.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <pthread.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <windows.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifndef HAVE_COMPILER_TLS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <process.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <OS.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <TLS.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(SOLARIS)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <note.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/* #define DEBUG_THREADS */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic int libxml_is_threaded = -1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef __GNUC__
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef linux
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_once (pthread_once_t *__once_control,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync void (*__init_routine) (void))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern void *pthread_getspecific (pthread_key_t __key)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_setspecific (pthread_key_t __key,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __const void *__pointer)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_key_create (pthread_key_t *__key,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync void (*__destr_function) (void *))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_mutex_init ()
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_mutex_destroy ()
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_mutex_lock ()
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_mutex_unlock ()
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_cond_init ()
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_equal ()
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern pthread_t pthread_self ()
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_key_create ()
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncextern int pthread_cond_signal ()
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __attribute((weak));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* linux */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* __GNUC__ */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* HAVE_PTHREAD_H */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * TODO: this module still uses malloc/free and not xmlMalloc/xmlFree
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * to avoid some crazyness since xmlMalloc/xmlFree may actually
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * be hosted on allocated blocks needing them for the allocation ...
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlMutex are a simple mutual exception locks
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstruct _xmlMutex {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_t lock;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync HANDLE mutex;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync sem_id sem;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync thread_id tid;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int empty;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync};
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlRMutex are reentrant mutual exception locks
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstruct _xmlRMutex {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_t lock;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync unsigned int held;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync unsigned int waiters;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_t tid;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_cond_t cv;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync CRITICAL_SECTION cs;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync unsigned int count;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlMutexPtr lock;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync thread_id tid;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int32 count;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int empty;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync};
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * This module still has some internal static data.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * - xmlLibraryLock a global lock
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * - globalkey used for per-thread data
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic pthread_key_t globalkey;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic pthread_t mainthread;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic pthread_once_t once_control = PTHREAD_ONCE_INIT;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic pthread_mutex_t global_init_lock = PTHREAD_MUTEX_INITIALIZER;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(HAVE_COMPILER_TLS)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic __declspec(thread) xmlGlobalState tlstate;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic __declspec(thread) int tlstate_inited = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else /* HAVE_COMPILER_TLS */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic DWORD globalkey = TLS_OUT_OF_INDEXES;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* HAVE_COMPILER_TLS */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic DWORD mainthread;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic struct
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync DWORD done;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync DWORD control;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync} run_once = { 0, 0 };
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic volatile LPCRITICAL_SECTION global_init_lock = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/* endif HAVE_WIN32_THREADS */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncint32 globalkey = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncthread_id mainthread = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncint32 run_once_init = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic int32 global_init_lock = -1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic vint32 global_init_count = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlRMutexPtr xmlLibraryLock = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef LIBXML_THREAD_ENABLED
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void xmlOnceInit(void);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlNewMutex:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlNewMutex() is used to allocate a libxml2 token struct for use in
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * synchronizing access to data.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns a new simple mutex pointer or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlMutexPtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlNewMutex(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlMutexPtr tok;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((tok = malloc(sizeof(xmlMutex))) == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded != 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_init(&tok->lock, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->mutex = CreateMutex(NULL, FALSE, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((tok->sem = create_sem(1, "xmlMutex")) < B_OK) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync free(tok);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->tid = -1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (tok);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlFreeMutex:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @tok: the simple mutex
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlFreeMutex() is used to reclaim resources associated with a libxml2 token
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * struct.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlFreeMutex(xmlMutexPtr tok)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok == NULL) return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded != 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_destroy(&tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync CloseHandle(tok->mutex);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync delete_sem(tok->sem);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync free(tok);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlMutexLock:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @tok: the simple mutex
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlMutexLock() is used to lock a libxml2 token.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlMutexLock(xmlMutexPtr tok)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded != 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_lock(&tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync WaitForSingleObject(tok->mutex, INFINITE);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (acquire_sem(tok->sem) != B_NO_ERROR) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef DEBUG_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGenericError(xmlGenericErrorContext, "xmlMutexLock():BeOS:Couldn't aquire semaphore\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync exit();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->tid = find_thread(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlMutexUnlock:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @tok: the simple mutex
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlMutexUnlock() is used to unlock a libxml2 token.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlMutexUnlock(xmlMutexPtr tok)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded != 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_unlock(&tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ReleaseMutex(tok->mutex);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok->tid == find_thread(NULL)) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->tid = -1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync release_sem(tok->sem);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlNewRMutex:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlRNewMutex() is used to allocate a reentrant mutex for use in
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * synchronizing access to data. token_r is a re-entrant lock and thus useful
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * for synchronizing access to data structures that may be manipulated in a
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * recursive fashion.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the new reentrant mutex pointer or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlRMutexPtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlNewRMutex(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlRMutexPtr tok;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((tok = malloc(sizeof(xmlRMutex))) == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded != 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_init(&tok->lock, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->held = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->waiters = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_cond_init(&tok->cv, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync InitializeCriticalSection(&tok->cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->count = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((tok->lock = xmlNewMutex()) == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync free(tok);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->count = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (tok);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlFreeRMutex:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @tok: the reentrant mutex
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlRFreeMutex() is used to reclaim resources associated with a
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * reentrant mutex.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlFreeRMutex(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded != 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_destroy(&tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_cond_destroy(&tok->cv);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync DeleteCriticalSection(&tok->cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeMutex(tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync free(tok);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlRMutexLock:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @tok: the reentrant mutex
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlRMutexLock() is used to lock a libxml2 token_r.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlRMutexLock(xmlRMutexPtr tok)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded == 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_lock(&tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok->held) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (pthread_equal(tok->tid, pthread_self())) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->held++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_unlock(&tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->waiters++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (tok->held)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_cond_wait(&tok->cv, &tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->waiters--;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->tid = pthread_self();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->held = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_unlock(&tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync EnterCriticalSection(&tok->cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ++tok->count;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok->lock->tid == find_thread(NULL)) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->count++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlMutexLock(tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->count = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlRMutexUnlock:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @tok: the reentrant mutex
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlRMutexUnlock() is used to unlock a libxml2 token_r.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded == 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_lock(&tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->held--;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok->held == 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok->waiters)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_cond_signal(&tok->cv);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->tid = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_unlock(&tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (!--tok->count)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync LeaveCriticalSection(&tok->cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok->lock->tid == find_thread(NULL)) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tok->count--;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tok->count == 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlMutexUnlock(tok->lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlGlobalInitMutexLock
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Makes sure that the global initialization mutex is initialized and
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * locks it.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync__xmlGlobalInitMutexLock(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* Make sure the global init lock is initialized and then lock it. */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* The mutex is statically initialized, so we just lock it. */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_lock(&global_init_lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync LPCRITICAL_SECTION cs;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* Create a new critical section */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (global_init_lock == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cs = malloc(sizeof(CRITICAL_SECTION));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync InitializeCriticalSection(cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* Swap it into the global_init_lock */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef InterlockedCompareExchangePointer
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync InterlockedCompareExchangePointer(&global_init_lock, cs, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else /* Use older void* version */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync InterlockedCompareExchange((void **)&global_init_lock, (void *)cs, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* InterlockedCompareExchangePointer */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* If another thread successfully recorded its critical
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * section in the global_init_lock then discard the one
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * allocated by this thread. */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (global_init_lock != cs) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync DeleteCriticalSection(cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync free(cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* Lock the chosen critical section */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync EnterCriticalSection(global_init_lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int32 sem;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* Allocate a new semaphore */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync sem = create_sem(1, "xmlGlobalinitMutex");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (global_init_lock == -1) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (atomic_add(&global_init_count, 1) == 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync global_init_lock = sem;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync snooze(1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync atomic_add(&global_init_count, -1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* If another thread successfully recorded its critical
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * section in the global_init_lock then discard the one
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * allocated by this thread. */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (global_init_lock != sem)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync delete_sem(sem);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* Acquire the chosen semaphore */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (acquire_sem(global_init_lock) != B_NO_ERROR) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef DEBUG_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGenericError(xmlGenericErrorContext, "xmlGlobalInitMutexLock():BeOS:Couldn't acquire semaphore\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync exit();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync__xmlGlobalInitMutexUnlock(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_mutex_unlock(&global_init_lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync LeaveCriticalSection(global_init_lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync release_sem(global_init_lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlGlobalInitMutexDestroy
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Makes sure that the global initialization mutex is destroyed before
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * application termination.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid __xmlGlobalInitMutexDestroy(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (global_init_lock != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync DeleteCriticalSection(global_init_lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync free(global_init_lock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync global_init_lock = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/************************************************************************
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Per thread global state handling *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ************************************************************************/
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef LIBXML_THREAD_ENABLED
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef xmlLastError
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#undef xmlLastError
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlFreeGlobalState:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @state: a thread global state
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlFreeGlobalState() is called when a thread terminates with a non-NULL
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * global state. It is is used here to reclaim memory resources.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlFreeGlobalState(void *state)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalState *gs = (xmlGlobalState *) state;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* free any memory allocated in the thread's xmlLastError */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlResetError(&(gs->xmlLastError));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync free(state);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlNewGlobalState:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlNewGlobalState() allocates a global state. This structure is used to
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * hold all data for use by a thread when supporting backwards compatibility
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * of libxml2 to pre-thread-safe behaviour.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the newly allocated xmlGlobalStatePtr or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlGlobalStatePtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlNewGlobalState(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalState *gs;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync gs = malloc(sizeof(xmlGlobalState));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (gs == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync memset(gs, 0, sizeof(xmlGlobalState));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlInitializeGlobalState(gs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (gs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* LIBXML_THREAD_ENABLED */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if !defined(HAVE_COMPILER_TLS)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsynctypedef struct _xmlGlobalStateCleanupHelperParams
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync HANDLE thread;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync void *memory;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync} xmlGlobalStateCleanupHelperParams;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void XMLCDECL xmlGlobalStateCleanupHelper (void *p)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalStateCleanupHelperParams *params = (xmlGlobalStateCleanupHelperParams *) p;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync WaitForSingleObject(params->thread, INFINITE);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync CloseHandle(params->thread);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeGlobalState(params->memory);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync free(params);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync _endthread();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else /* LIBXML_STATIC && !LIBXML_STATIC_FOR_DLL */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsynctypedef struct _xmlGlobalStateCleanupHelperParams
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync void *memory;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync struct _xmlGlobalStateCleanupHelperParams * prev;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync struct _xmlGlobalStateCleanupHelperParams * next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync} xmlGlobalStateCleanupHelperParams;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlGlobalStateCleanupHelperParams * cleanup_helpers_head = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic CRITICAL_SECTION cleanup_helpers_cs;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* LIBXMLSTATIC && !LIBXML_STATIC_FOR_DLL */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* HAVE_COMPILER_TLS */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* HAVE_WIN32_THREADS */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlGlobalStateCleanup:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @data: unused parameter
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Used for Beos only
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid xmlGlobalStateCleanup(void *data)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync void *globalval = tls_get(globalkey);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (globalval != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeGlobalState(globalval);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlGetGlobalState:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlGetGlobalState() is called to retrieve the global state for a thread.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the thread global state or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlGlobalStatePtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlGetGlobalState(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalState *globalval;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded == 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_once(&once_control, xmlOnceInit);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((globalval = (xmlGlobalState *)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_getspecific(globalkey)) == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalState *tsd = xmlNewGlobalState();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_setspecific(globalkey, tsd);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (tsd);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (globalval);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(HAVE_COMPILER_TLS)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (!tlstate_inited) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tlstate_inited = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlInitializeGlobalState(&tlstate);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return &tlstate;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else /* HAVE_COMPILER_TLS */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalState *globalval;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalStateCleanupHelperParams * p;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlOnceInit();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync globalval = (xmlGlobalState *)TlsGetValue(globalkey);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync p = (xmlGlobalStateCleanupHelperParams*)TlsGetValue(globalkey);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync globalval = (xmlGlobalState *)(p ? p->memory : NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (globalval == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalState *tsd = xmlNewGlobalState();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync p = (xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync p->memory = tsd;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync GetCurrentProcess(), &p->thread, 0, TRUE, DUPLICATE_SAME_ACCESS);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync TlsSetValue(globalkey, tsd);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync _beginthread(xmlGlobalStateCleanupHelper, 0, p);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync EnterCriticalSection(&cleanup_helpers_cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (cleanup_helpers_head != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cleanup_helpers_head->prev = p;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync p->next = cleanup_helpers_head;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync p->prev = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cleanup_helpers_head = p;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync TlsSetValue(globalkey, p);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync LeaveCriticalSection(&cleanup_helpers_cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (tsd);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (globalval);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* HAVE_COMPILER_TLS */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalState *globalval;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlOnceInit();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((globalval = (xmlGlobalState *)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tls_get(globalkey)) == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalState *tsd = xmlNewGlobalState();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tls_set(globalkey, tsd);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync on_exit_thread(xmlGlobalStateCleanup, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (tsd);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (globalval);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/************************************************************************
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Library wide thread interfaces *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ************************************************************************/
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlGetThreadId:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlGetThreadId() find the current thread ID number
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the current thread ID number
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncint
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlGetThreadId(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded == 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(0);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return((int) pthread_self());
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return GetCurrentThreadId();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return find_thread(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return((int) 0);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlIsMainThread:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlIsMainThread() check whether the current thread is the main thread.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns 1 if the current thread is the main thread, 0 otherwise
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncint
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlIsMainThread(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded == -1)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlInitThreads();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded == 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pthread_once(&once_control, xmlOnceInit);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlOnceInit ();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlOnceInit();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef DEBUG_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(mainthread == pthread_self());
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_WIN32_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(mainthread == GetCurrentThreadId ());
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#elif defined HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(mainthread == find_thread(NULL));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlLockLibrary:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlLockLibrary() is used to take out a re-entrant lock on the libxml2
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * library.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlLockLibrary(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef DEBUG_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGenericError(xmlGenericErrorContext, "xmlLockLibrary()\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlRMutexLock(xmlLibraryLock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlUnlockLibrary:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlUnlockLibrary() is used to release a re-entrant lock on the libxml2
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * library.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlUnlockLibrary(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef DEBUG_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGenericError(xmlGenericErrorContext, "xmlUnlockLibrary()\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlRMutexUnlock(xmlLibraryLock);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlInitThreads:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlInitThreads() is used to to initialize all the thread related
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * data of the libxml2 library.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlInitThreads(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef DEBUG_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGenericError(xmlGenericErrorContext, "xmlInitThreads()\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync InitializeCriticalSection(&cleanup_helpers_cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (libxml_is_threaded == -1) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((pthread_once != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_getspecific != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_setspecific != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_key_create != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_mutex_init != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_mutex_destroy != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_mutex_lock != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_mutex_unlock != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_cond_init != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_equal != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_self != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_key_create != NULL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (pthread_cond_signal != NULL)) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync libxml_is_threaded = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/* fprintf(stderr, "Running multithreaded\n"); */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/* fprintf(stderr, "Running without multithread\n"); */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync libxml_is_threaded = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlCleanupThreads:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlCleanupThreads() is used to to cleanup all the thread related
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * data of the libxml2 library once processing has ended.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlCleanupThreads(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef DEBUG_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (globalkey != TLS_OUT_OF_INDEXES) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalStateCleanupHelperParams * p;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync EnterCriticalSection(&cleanup_helpers_cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync p = cleanup_helpers_head;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (p != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalStateCleanupHelperParams * temp = p;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync p = p->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeGlobalState(temp->memory);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync free(temp);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cleanup_helpers_head = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync LeaveCriticalSection(&cleanup_helpers_cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync TlsFree(globalkey);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync globalkey = TLS_OUT_OF_INDEXES;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync DeleteCriticalSection(&cleanup_helpers_cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef LIBXML_THREAD_ENABLED
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlOnceInit
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlOnceInit() is used to initialize the value of mainthread for use
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * in other routines. This function should only be called using
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * pthread_once() in association with the once_control variable to ensure
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * that the function is only called once. See man pthread_once for more
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * details.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlOnceInit(void) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_PTHREAD_H
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (void) pthread_key_create(&globalkey, xmlFreeGlobalState);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync mainthread = pthread_self();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(HAVE_WIN32_THREADS)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (!run_once.done) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (InterlockedIncrement(&run_once.control) == 1)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if !defined(HAVE_COMPILER_TLS)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync globalkey = TlsAlloc();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync mainthread = GetCurrentThreadId();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync run_once.done = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* Another thread is working; give up our slice and
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * wait until they're done. */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (!run_once.done)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync Sleep(0);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef HAVE_BEOS_THREADS
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (atomic_add(&run_once_init, 1) == 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync globalkey = tls_allocate();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tls_set(globalkey, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync mainthread = find_thread(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync atomic_add(&run_once_init, -1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * DllMain:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @hinstDLL: handle to DLL instance
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @fdwReason: Reason code for entry
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @lpvReserved: generic pointer (depends upon reason code)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Entry point for Windows library. It is being used to free thread-specific
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * storage.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns TRUE always
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if defined(LIBXML_STATIC_FOR_DLL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncBOOL XMLCALL xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#else
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncBOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync switch(fdwReason) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case DLL_THREAD_DETACH:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (globalkey != TLS_OUT_OF_INDEXES) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalState *globalval = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGlobalStateCleanupHelperParams * p =
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (xmlGlobalStateCleanupHelperParams*)TlsGetValue(globalkey);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync globalval = (xmlGlobalState *)(p ? p->memory : NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (globalval) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeGlobalState(globalval);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync TlsSetValue(globalkey,NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (p)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync EnterCriticalSection(&cleanup_helpers_cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (p == cleanup_helpers_head)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cleanup_helpers_head = p->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync else
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync p->prev->next = p->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (p->next != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync p->next->prev = p->prev;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync LeaveCriticalSection(&cleanup_helpers_cs);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync free(p);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync break;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return TRUE;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define bottom_threads
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include "elfgcchack.h"