21#elif defined HAVE_WIN32_THREADS
22#define WIN32_LEAN_AND_MEAN
24#ifndef HAVE_COMPILER_TLS
29#ifdef HAVE_BEOS_THREADS
42#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 303) && \
43 defined(__GLIBC__) && defined(__linux__)
45static int libxml_is_threaded = -1;
47#define XML_PTHREAD_WEAK
49#pragma weak pthread_once
50#pragma weak pthread_getspecific
51#pragma weak pthread_setspecific
52#pragma weak pthread_key_create
53#pragma weak pthread_key_delete
54#pragma weak pthread_mutex_init
55#pragma weak pthread_mutex_destroy
56#pragma weak pthread_mutex_lock
57#pragma weak pthread_mutex_unlock
58#pragma weak pthread_cond_init
59#pragma weak pthread_cond_destroy
60#pragma weak pthread_cond_wait
61#pragma weak pthread_equal
62#pragma weak pthread_self
63#pragma weak pthread_key_create
64#pragma weak pthread_key_delete
65#pragma weak pthread_cond_signal
69static int libxml_is_threaded = 1;
87#elif defined HAVE_WIN32_THREADS
89#elif defined HAVE_BEOS_THREADS
102 pthread_mutex_t
lock;
104 unsigned int waiters;
107#elif defined HAVE_WIN32_THREADS
109#elif defined HAVE_BEOS_THREADS
125static pthread_key_t globalkey;
126static pthread_t mainthread;
127static pthread_once_t once_control = PTHREAD_ONCE_INIT;
128static pthread_once_t once_control_init = PTHREAD_ONCE_INIT;
129static pthread_mutex_t global_init_lock = PTHREAD_MUTEX_INITIALIZER;
130#elif defined HAVE_WIN32_THREADS
131#if defined(HAVE_COMPILER_TLS)
137static DWORD mainthread;
145#elif defined HAVE_BEOS_THREADS
148int32 run_once_init = 0;
149static int32 global_init_lock = -1;
150static vint32 global_init_count = 0;
155#ifdef LIBXML_THREAD_ENABLED
156static void xmlOnceInit(
void);
175 if (libxml_is_threaded != 0)
176 pthread_mutex_init(&tok->lock,
NULL);
177#elif defined HAVE_WIN32_THREADS
179#elif defined HAVE_BEOS_THREADS
180 if ((tok->sem = create_sem(1,
"xmlMutex")) < B_OK) {
203 if (libxml_is_threaded != 0)
204 pthread_mutex_destroy(&tok->lock);
205#elif defined HAVE_WIN32_THREADS
207#elif defined HAVE_BEOS_THREADS
208 delete_sem(tok->sem);
225 if (libxml_is_threaded != 0)
226 pthread_mutex_lock(&tok->lock);
227#elif defined HAVE_WIN32_THREADS
229#elif defined HAVE_BEOS_THREADS
230 if (acquire_sem(tok->sem) != B_NO_ERROR) {
233 "xmlMutexLock():BeOS:Couldn't acquire semaphore\n");
253 if (libxml_is_threaded != 0)
254 pthread_mutex_unlock(&tok->lock);
255#elif defined HAVE_WIN32_THREADS
257#elif defined HAVE_BEOS_THREADS
260 release_sem(tok->sem);
283 if (libxml_is_threaded != 0) {
284 pthread_mutex_init(&tok->lock,
NULL);
287 pthread_cond_init(&tok->cv,
NULL);
289#elif defined HAVE_WIN32_THREADS
291#elif defined HAVE_BEOS_THREADS
314 if (libxml_is_threaded != 0) {
315 pthread_mutex_destroy(&tok->lock);
316 pthread_cond_destroy(&tok->cv);
318#elif defined HAVE_WIN32_THREADS
320#elif defined HAVE_BEOS_THREADS
338 if (libxml_is_threaded == 0)
341 pthread_mutex_lock(&tok->lock);
343 if (pthread_equal(tok->tid, pthread_self())) {
345 pthread_mutex_unlock(&tok->lock);
350 pthread_cond_wait(&tok->cv, &tok->lock);
354 tok->tid = pthread_self();
356 pthread_mutex_unlock(&tok->lock);
357#elif defined HAVE_WIN32_THREADS
359#elif defined HAVE_BEOS_THREADS
382 if (libxml_is_threaded == 0)
385 pthread_mutex_lock(&tok->lock);
387 if (tok->held == 0) {
389 pthread_cond_signal(&tok->cv);
390 memset(&tok->tid, 0,
sizeof(tok->tid));
392 pthread_mutex_unlock(&tok->lock);
393#elif defined HAVE_WIN32_THREADS
395#elif defined HAVE_BEOS_THREADS
398 if (tok->count == 0) {
418#ifdef XML_PTHREAD_WEAK
419 if (pthread_mutex_lock ==
NULL)
422 pthread_mutex_lock(&global_init_lock);
423#elif defined HAVE_WIN32_THREADS
427 if (global_init_lock ==
NULL) {
431 "xmlGlobalInitMutexLock: out of memory\n");
437#ifdef InterlockedCompareExchangePointer
448 if (global_init_lock !=
cs) {
456#elif defined HAVE_BEOS_THREADS
460 sem = create_sem(1,
"xmlGlobalinitMutex");
462 while (global_init_lock == -1) {
464 global_init_lock =
sem;
474 if (global_init_lock !=
sem)
478 if (acquire_sem(global_init_lock) != B_NO_ERROR) {
481 "xmlGlobalInitMutexLock():BeOS:Couldn't acquire semaphore\n");
491#ifdef XML_PTHREAD_WEAK
492 if (pthread_mutex_unlock ==
NULL)
495 pthread_mutex_unlock(&global_init_lock);
496#elif defined HAVE_WIN32_THREADS
497 if (global_init_lock !=
NULL) {
500#elif defined HAVE_BEOS_THREADS
501 release_sem(global_init_lock);
515#elif defined HAVE_WIN32_THREADS
516 if (global_init_lock !=
NULL) {
518 free(global_init_lock);
519 global_init_lock =
NULL;
530#ifdef LIBXML_THREAD_ENABLED
543xmlFreeGlobalState(
void *
state)
562xmlNewGlobalState(
void)
569 "xmlGetGlobalState: out of memory\n");
580#elif defined HAVE_WIN32_THREADS
581#if !defined(HAVE_COMPILER_TLS)
582#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
583typedef struct _xmlGlobalStateCleanupHelperParams {
586} xmlGlobalStateCleanupHelperParams;
589xmlGlobalStateCleanupHelper(
void *
p)
591 xmlGlobalStateCleanupHelperParams *
params =
592 (xmlGlobalStateCleanupHelperParams *)
p;
595 xmlFreeGlobalState(
params->memory);
601typedef struct _xmlGlobalStateCleanupHelperParams {
603 struct _xmlGlobalStateCleanupHelperParams *prev;
604 struct _xmlGlobalStateCleanupHelperParams *
next;
605} xmlGlobalStateCleanupHelperParams;
607static xmlGlobalStateCleanupHelperParams *cleanup_helpers_head =
NULL;
614#if defined HAVE_BEOS_THREADS
623xmlGlobalStateCleanup(
void *
data)
625 void *globalval = tls_get(globalkey);
627 if (globalval !=
NULL)
628 xmlFreeGlobalState(globalval);
645 if (libxml_is_threaded == 0)
648 pthread_once(&once_control, xmlOnceInit);
651 pthread_getspecific(globalkey)) ==
NULL) {
656 pthread_setspecific(globalkey, tsd);
660#elif defined HAVE_WIN32_THREADS
661#if defined(HAVE_COMPILER_TLS)
662 if (!tlstate_inited) {
669 xmlGlobalStateCleanupHelperParams *
p;
672#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
675 p = (xmlGlobalStateCleanupHelperParams *)
TlsGetValue(globalkey);
678 if (globalval ==
NULL) {
683 p = (xmlGlobalStateCleanupHelperParams *)
684 malloc(
sizeof(xmlGlobalStateCleanupHelperParams));
687 "xmlGetGlobalState: out of memory\n");
688 xmlFreeGlobalState(tsd);
692#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
700 if (cleanup_helpers_head !=
NULL) {
701 cleanup_helpers_head->prev =
p;
703 p->next = cleanup_helpers_head;
705 cleanup_helpers_head =
p;
714#elif defined HAVE_BEOS_THREADS
724 tls_set(globalkey, tsd);
725 on_exit_thread(xmlGlobalStateCleanup,
NULL);
756 if (libxml_is_threaded == 0)
762#elif defined HAVE_WIN32_THREADS
764#elif defined HAVE_BEOS_THREADS
782 if (libxml_is_threaded == -1)
784 if (libxml_is_threaded == 0)
786 pthread_once(&once_control, xmlOnceInit);
787#elif defined HAVE_WIN32_THREADS
789#elif defined HAVE_BEOS_THREADS
797 return (pthread_equal(mainthread,pthread_self()));
798#elif defined HAVE_WIN32_THREADS
800#elif defined HAVE_BEOS_THREADS
850#ifdef XML_PTHREAD_WEAK
851 if (libxml_is_threaded == -1) {
852 if ((pthread_once !=
NULL) &&
853 (pthread_getspecific !=
NULL) &&
854 (pthread_setspecific !=
NULL) &&
855 (pthread_key_create !=
NULL) &&
856 (pthread_key_delete !=
NULL) &&
857 (pthread_mutex_init !=
NULL) &&
858 (pthread_mutex_destroy !=
NULL) &&
859 (pthread_mutex_lock !=
NULL) &&
860 (pthread_mutex_unlock !=
NULL) &&
861 (pthread_cond_init !=
NULL) &&
862 (pthread_cond_destroy !=
NULL) &&
863 (pthread_cond_wait !=
NULL) &&
864 (pthread_equal !=
NULL) &&
865 (pthread_self !=
NULL) &&
866 (pthread_cond_signal !=
NULL)) {
867 libxml_is_threaded = 1;
873 libxml_is_threaded = 0;
906 if (libxml_is_threaded != 0)
907 pthread_key_delete(globalkey);
908 once_control = once_control_init;
909#elif defined(HAVE_WIN32_THREADS)
910#if !defined(HAVE_COMPILER_TLS)
912#if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)
913 xmlGlobalStateCleanupHelperParams *
p;
916 p = cleanup_helpers_head;
918 xmlGlobalStateCleanupHelperParams *
temp =
p;
921 xmlFreeGlobalState(
temp->memory);
924 cleanup_helpers_head = 0;
930#if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)
935 run_once.control = 0;
939#ifdef LIBXML_THREAD_ENABLED
954 (
void) pthread_key_create(&globalkey, xmlFreeGlobalState);
955 mainthread = pthread_self();
957#elif defined(HAVE_WIN32_THREADS)
958 if (!run_once.done) {
960#if !defined(HAVE_COMPILER_TLS)
961#if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)
972 while (!run_once.done)
976#elif defined HAVE_BEOS_THREADS
978 globalkey = tls_allocate();
979 tls_set(globalkey,
NULL);
1000#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
1001#if defined(LIBXML_STATIC_FOR_DLL)
1021 switch (fdwReason) {
1025 xmlGlobalStateCleanupHelperParams *
p =
1026 (xmlGlobalStateCleanupHelperParams *)
1030 xmlFreeGlobalState(globalval);
1035 if (
p == cleanup_helpers_head)
1036 cleanup_helpers_head =
p->next;
1038 p->prev->next =
p->next;
1039 if (
p->next !=
NULL)
1040 p->next->prev =
p->prev;
#define InterlockedIncrement
static void atomic_add(int volatile i, atomic_t volatile *v)
#define DLL_THREAD_DETACH
#define GetCurrentProcess()
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
LPVOID WINAPI TlsGetValue(IN DWORD Index)
DWORD WINAPI TlsAlloc(VOID)
BOOL WINAPI TlsSetValue(IN DWORD Index, IN LPVOID Value)
BOOL WINAPI TlsFree(IN DWORD Index)
GLuint GLuint GLsizei count
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLenum const GLfloat * params
#define InterlockedCompareExchangePointer
#define InterlockedCompareExchange
BOOL WINAPI DllMain(IN HINSTANCE hinstDLL, IN DWORD dwReason, IN LPVOID lpvReserved)
PETHREAD find_thread(_In_ UINT_PTR Pid, _In_ UINT_PTR Tid)
static IN DWORD IN LPVOID lpvReserved
#define memcpy(s1, s2, n)
static char memory[1024 *256]
static unsigned __int64 next
_CRTIMP uintptr_t __cdecl _beginthread(_In_ void(__cdecl *_StartAddress)(void *), _In_ unsigned _StackSize, _In_opt_ void *_ArgList)
_CRTIMP void __cdecl _endthread(void)
XMLPUBFUN void XMLCALL xmlInitializeGlobalState(xmlGlobalStatePtr gs)
XMLPUBVAR void * xmlGenericErrorContext
XMLPUBVAR xmlGenericErrorFunc xmlGenericError
int __xmlInitializeDict(void)
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
void __xmlGlobalInitMutexDestroy(void)
xmlMutexPtr xmlNewMutex(void)
void xmlLockLibrary(void)
xmlRMutexPtr xmlNewRMutex(void)
void xmlFreeRMutex(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
void xmlInitThreads(void)
void xmlUnlockLibrary(void)
void __xmlGlobalInitMutexLock(void)
void xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
int xmlIsMainThread(void)
void xmlMutexLock(xmlMutexPtr tok)
void xmlMutexUnlock(xmlMutexPtr tok)
static xmlRMutexPtr xmlLibraryLock
void xmlRMutexLock(xmlRMutexPtr tok)
void xmlFreeMutex(xmlMutexPtr tok)
void xmlCleanupThreads(void)
xmlGlobalStatePtr xmlGetGlobalState(void)
void __xmlGlobalInitMutexUnlock(void)
HANDLE WINAPI GetCurrentThread(void)
DWORD WINAPI GetCurrentThreadId(void)
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define TLS_OUT_OF_INDEXES
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define DUPLICATE_SAME_ACCESS
XMLPUBFUN void XMLCALL xmlResetError(xmlErrorPtr err)