mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-08-08 17:42:14 +03:00
improvements to the Windows-side of thread handling
This commit is contained in:
141
threads.c
141
threads.c
@@ -27,9 +27,10 @@
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_WIN32_THREADS
|
#ifdef HAVE_WIN32_THREADS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#ifndef _MSC_VER
|
#ifndef HAVE_COMPILER_TLS
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -53,7 +54,7 @@ struct _xmlMutex {
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_mutex_t lock;
|
pthread_mutex_t lock;
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
HANDLE mutex;
|
HANDLE mutex;
|
||||||
#else
|
#else
|
||||||
int empty;
|
int empty;
|
||||||
#endif
|
#endif
|
||||||
@@ -70,8 +71,8 @@ struct _xmlRMutex {
|
|||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
pthread_cond_t cv;
|
pthread_cond_t cv;
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
CRITICAL_SECTION cs;
|
CRITICAL_SECTION cs;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
#else
|
#else
|
||||||
int empty;
|
int empty;
|
||||||
#endif
|
#endif
|
||||||
@@ -87,15 +88,16 @@ static pthread_key_t globalkey;
|
|||||||
static pthread_t mainthread;
|
static pthread_t mainthread;
|
||||||
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
|
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
#if defined(HAVE_COMPILER_TLS)
|
||||||
static __declspec (thread) xmlGlobalState tlstate;
|
static __declspec(thread) xmlGlobalState tlstate;
|
||||||
static __declspec (thread) int tlstate_inited = 0;
|
static __declspec(thread) int tlstate_inited = 0;
|
||||||
#else
|
#else /* HAVE_COMPILER_TLS */
|
||||||
static DWORD globalkey;
|
static DWORD globalkey;
|
||||||
#endif /* _MSC_VER */
|
#endif /* HAVE_COMPILER_TLS */
|
||||||
static DWORD mainthread;
|
static DWORD mainthread;
|
||||||
static int run_once_init = 1;
|
static int run_once_init = 1;
|
||||||
#endif /* HAVE_WIN32_THREADS */
|
#endif /* HAVE_WIN32_THREADS */
|
||||||
|
|
||||||
static xmlRMutexPtr xmlLibraryLock = NULL;
|
static xmlRMutexPtr xmlLibraryLock = NULL;
|
||||||
static void xmlOnceInit(void);
|
static void xmlOnceInit(void);
|
||||||
|
|
||||||
@@ -117,7 +119,7 @@ xmlNewMutex(void)
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_mutex_init(&tok->lock, NULL);
|
pthread_mutex_init(&tok->lock, NULL);
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
tok->mutex = CreateMutex (NULL, FALSE, NULL);
|
tok->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||||
#endif
|
#endif
|
||||||
return (tok);
|
return (tok);
|
||||||
}
|
}
|
||||||
@@ -135,7 +137,7 @@ xmlFreeMutex(xmlMutexPtr tok)
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_mutex_destroy(&tok->lock);
|
pthread_mutex_destroy(&tok->lock);
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
CloseHandle (tok->mutex);
|
CloseHandle(tok->mutex);
|
||||||
#endif
|
#endif
|
||||||
free(tok);
|
free(tok);
|
||||||
}
|
}
|
||||||
@@ -152,7 +154,7 @@ xmlMutexLock(xmlMutexPtr tok ATTRIBUTE_UNUSED)
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_mutex_lock(&tok->lock);
|
pthread_mutex_lock(&tok->lock);
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
WaitForSingleObject (tok->mutex, INFINITE);
|
WaitForSingleObject(tok->mutex, INFINITE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -169,7 +171,7 @@ xmlMutexUnlock(xmlMutexPtr tok ATTRIBUTE_UNUSED)
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_mutex_unlock(&tok->lock);
|
pthread_mutex_unlock(&tok->lock);
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
ReleaseMutex (tok->mutex);
|
ReleaseMutex(tok->mutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,8 +197,8 @@ xmlNewRMutex(void)
|
|||||||
tok->held = 0;
|
tok->held = 0;
|
||||||
tok->waiters = 0;
|
tok->waiters = 0;
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
InitializeCriticalSection (&tok->cs);
|
InitializeCriticalSection(&tok->cs);
|
||||||
tok->count = 0;
|
tok->count = 0;
|
||||||
#endif
|
#endif
|
||||||
return (tok);
|
return (tok);
|
||||||
}
|
}
|
||||||
@@ -214,7 +216,7 @@ xmlFreeRMutex(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_mutex_destroy(&tok->lock);
|
pthread_mutex_destroy(&tok->lock);
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
DeleteCriticalSection (&tok->cs);
|
DeleteCriticalSection(&tok->cs);
|
||||||
#endif
|
#endif
|
||||||
free(tok);
|
free(tok);
|
||||||
}
|
}
|
||||||
@@ -246,8 +248,8 @@ xmlRMutexLock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
|
|||||||
tok->held = 1;
|
tok->held = 1;
|
||||||
pthread_mutex_unlock(&tok->lock);
|
pthread_mutex_unlock(&tok->lock);
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
EnterCriticalSection (&tok->cs);
|
EnterCriticalSection(&tok->cs);
|
||||||
++tok->count;
|
++tok->count;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +272,8 @@ xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
|
|||||||
}
|
}
|
||||||
pthread_mutex_unlock(&tok->lock);
|
pthread_mutex_unlock(&tok->lock);
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
if (!--tok->count) LeaveCriticalSection (&tok->cs);
|
if (!--tok->count)
|
||||||
|
LeaveCriticalSection(&tok->cs);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +284,6 @@ xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
#ifdef LIBXML_THREAD_ENABLED
|
#ifdef LIBXML_THREAD_ENABLED
|
||||||
#ifndef _MSC_VER
|
|
||||||
/**
|
/**
|
||||||
* xmlFreeGlobalState:
|
* xmlFreeGlobalState:
|
||||||
* @state: a thread global state
|
* @state: a thread global state
|
||||||
@@ -317,7 +319,6 @@ xmlNewGlobalState(void)
|
|||||||
xmlInitializeGlobalState(gs);
|
xmlInitializeGlobalState(gs);
|
||||||
return (gs);
|
return (gs);
|
||||||
}
|
}
|
||||||
#endif /* _MSC_VER */
|
|
||||||
#endif /* LIBXML_THREAD_ENABLED */
|
#endif /* LIBXML_THREAD_ENABLED */
|
||||||
|
|
||||||
|
|
||||||
@@ -330,23 +331,23 @@ xmlNewGlobalState(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_WIN32_THREADS
|
#ifdef HAVE_WIN32_THREADS
|
||||||
#if !defined(_MSC_VER) && !defined(__BORLANDC__)
|
#if !defined(HAVE_COMPILER_TLS)
|
||||||
typedef struct _xmlGlobalStateCleanupHelperParams
|
typedef struct _xmlGlobalStateCleanupHelperParams
|
||||||
{
|
{
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
void *memory;
|
void *memory;
|
||||||
} xmlGlobalStateCleanupHelperParams;
|
} xmlGlobalStateCleanupHelperParams;
|
||||||
|
|
||||||
void __cdecl xmlGlobalStateCleanupHelper (void *p)
|
void xmlGlobalStateCleanupHelper (void *p)
|
||||||
{
|
{
|
||||||
xmlGlobalStateCleanupHelperParams *params = (xmlGlobalStateCleanupHelperParams *) p;
|
xmlGlobalStateCleanupHelperParams *params = (xmlGlobalStateCleanupHelperParams *) p;
|
||||||
WaitForSingleObject (params->thread, INFINITE);
|
WaitForSingleObject(params->thread, INFINITE);
|
||||||
CloseHandle (params->thread);
|
CloseHandle(params->thread);
|
||||||
xmlFreeGlobalState (params->memory);
|
xmlFreeGlobalState(params->memory);
|
||||||
free (params);
|
free(params);
|
||||||
_endthread ();
|
_endthread();
|
||||||
}
|
}
|
||||||
#endif /* _MSC_VER */
|
#endif /* HAVE_COMPILER_TLS */
|
||||||
#endif /* HAVE_WIN32_THREADS */
|
#endif /* HAVE_WIN32_THREADS */
|
||||||
|
|
||||||
xmlGlobalStatePtr
|
xmlGlobalStatePtr
|
||||||
@@ -358,7 +359,7 @@ xmlGetGlobalState(void)
|
|||||||
pthread_once(&once_control, xmlOnceInit);
|
pthread_once(&once_control, xmlOnceInit);
|
||||||
|
|
||||||
if ((globalval = (xmlGlobalState *)
|
if ((globalval = (xmlGlobalState *)
|
||||||
pthread_getspecific(globalkey)) == NULL) {
|
pthread_getspecific(globalkey)) == NULL) {
|
||||||
xmlGlobalState *tsd = xmlNewGlobalState();
|
xmlGlobalState *tsd = xmlNewGlobalState();
|
||||||
|
|
||||||
pthread_setspecific(globalkey, tsd);
|
pthread_setspecific(globalkey, tsd);
|
||||||
@@ -366,34 +367,33 @@ xmlGetGlobalState(void)
|
|||||||
}
|
}
|
||||||
return (globalval);
|
return (globalval);
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
#if defined(HAVE_COMPILER_TLS)
|
||||||
if (!tlstate_inited)
|
if (!tlstate_inited) {
|
||||||
{
|
tlstate_inited = 1;
|
||||||
tlstate_inited = 1;
|
xmlInitializeGlobalState(&tlstate);
|
||||||
xmlInitializeGlobalState (&tlstate);
|
}
|
||||||
}
|
return &tlstate;
|
||||||
|
#else /* HAVE_COMPILER_TLS */
|
||||||
|
xmlGlobalState *globalval;
|
||||||
|
|
||||||
return &tlstate;
|
if (run_once_init) {
|
||||||
#else /* !_MSC_VER */
|
run_once_init = 0;
|
||||||
xmlGlobalState *globalval;
|
xmlOnceInit();
|
||||||
|
}
|
||||||
|
if ((globalval = (xmlGlobalState *) TlsGetValue(globalkey)) == NULL) {
|
||||||
|
xmlGlobalState *tsd = xmlNewGlobalState();
|
||||||
|
xmlGlobalStateCleanupHelperParams *p =
|
||||||
|
(xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams));
|
||||||
|
p->memory = tsd;
|
||||||
|
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
|
||||||
|
GetCurrentProcess(), &p->thread, 0, TRUE, DUPLICATE_SAME_ACCESS);
|
||||||
|
TlsSetValue(globalkey, tsd);
|
||||||
|
_beginthread(xmlGlobalStateCleanupHelper, 0, p);
|
||||||
|
|
||||||
if (run_once_init) { run_once_init = 0; xmlOnceInit (); }
|
return (tsd);
|
||||||
|
}
|
||||||
if ((globalval = (xmlGlobalState *) TlsGetValue (globalkey)) == NULL)
|
return (globalval);
|
||||||
{
|
#endif /* HAVE_COMPILER_TLS */
|
||||||
xmlGlobalState *tsd = xmlNewGlobalState();
|
|
||||||
xmlGlobalStateCleanupHelperParams *p = (xmlGlobalStateCleanupHelperParams *) malloc (sizeof (xmlGlobalStateCleanupHelperParams));
|
|
||||||
|
|
||||||
p->memory = tsd;
|
|
||||||
DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), GetCurrentProcess (), &p->thread, 0, TRUE, DUPLICATE_SAME_ACCESS);
|
|
||||||
|
|
||||||
TlsSetValue (globalkey, tsd);
|
|
||||||
_beginthread (xmlGlobalStateCleanupHelper, 0, p);
|
|
||||||
|
|
||||||
return (tsd);
|
|
||||||
}
|
|
||||||
return (globalval);
|
|
||||||
#endif /* _MSC_VER */
|
|
||||||
#else
|
#else
|
||||||
return(NULL);
|
return(NULL);
|
||||||
#endif
|
#endif
|
||||||
@@ -418,7 +418,7 @@ xmlGetThreadId(void)
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
return((int) pthread_self());
|
return((int) pthread_self());
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
return GetCurrentThreadId ();
|
return GetCurrentThreadId();
|
||||||
#else
|
#else
|
||||||
return((int) 0);
|
return((int) 0);
|
||||||
#endif
|
#endif
|
||||||
@@ -437,7 +437,10 @@ xmlIsMainThread(void)
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_once(&once_control, xmlOnceInit);
|
pthread_once(&once_control, xmlOnceInit);
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
if (run_once_init) { run_once_init = 0; xmlOnceInit (); }
|
if (run_once_init) {
|
||||||
|
run_once_init = 0;
|
||||||
|
xmlOnceInit ();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_THREADS
|
#ifdef DEBUG_THREADS
|
||||||
@@ -446,7 +449,7 @@ xmlIsMainThread(void)
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
return(mainthread == pthread_self());
|
return(mainthread == pthread_self());
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#elif defined HAVE_WIN32_THREADS
|
||||||
return (mainthread == GetCurrentThreadId ());
|
return(mainthread == GetCurrentThreadId ());
|
||||||
#else
|
#else
|
||||||
return(1);
|
return(1);
|
||||||
#endif
|
#endif
|
||||||
@@ -522,12 +525,14 @@ xmlCleanupThreads(void)
|
|||||||
static void
|
static void
|
||||||
xmlOnceInit(void) {
|
xmlOnceInit(void) {
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
(void) pthread_key_create(&globalkey, xmlFreeGlobalState);
|
(void) pthread_key_create(&globalkey, xmlFreeGlobalState);
|
||||||
mainthread = pthread_self();
|
mainthread = pthread_self();
|
||||||
#elif defined HAVE_WIN32_THREADS
|
#endif
|
||||||
#if !defined(_MSC_VER) && !defined(__BORLANDC__)
|
|
||||||
globalkey = TlsAlloc ();
|
#if defined(HAVE_WIN32_THREADS)
|
||||||
#endif /* _MSC_VER */
|
#if !defined(HAVE_COMPILER_TLS)
|
||||||
mainthread = GetCurrentThreadId ();
|
globalkey = TlsAlloc();
|
||||||
|
#endif
|
||||||
|
mainthread = GetCurrentThreadId();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user