mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-02-04 01:47:02 +03:00
globals: Use thread-local storage if available
Also use thread-local storage to store globals on POSIX platforms. Most importantly, this makes sure that global variable access can't fail when allocating the global state struct.
This commit is contained in:
parent
e7b6ca156f
commit
b173b724d1
65
globals.c
65
globals.c
@ -43,6 +43,8 @@ static xmlMutex xmlThrDefMutex;
|
||||
type gs_##name;
|
||||
|
||||
struct _xmlGlobalState {
|
||||
int initialized;
|
||||
|
||||
#if defined(HAVE_WIN32_THREADS) && \
|
||||
defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
|
||||
void *threadHandle;
|
||||
@ -54,6 +56,12 @@ XML_GLOBALS
|
||||
#undef XML_OP
|
||||
};
|
||||
|
||||
#ifdef LIBXML_THREAD_ENABLED
|
||||
|
||||
#ifdef XML_THREAD_LOCAL
|
||||
static XML_THREAD_LOCAL xmlGlobalState globalState;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POSIX_THREADS
|
||||
|
||||
/*
|
||||
@ -73,23 +81,16 @@ static pthread_key_t globalkey;
|
||||
|
||||
#elif defined HAVE_WIN32_THREADS
|
||||
|
||||
#if defined(HAVE_COMPILER_TLS)
|
||||
|
||||
static __declspec(thread) xmlGlobalState tlstate;
|
||||
static __declspec(thread) int tlstate_inited = 0;
|
||||
|
||||
#else /* HAVE_COMPILER_TLS */
|
||||
|
||||
#ifndef XML_THREAD_LOCAL
|
||||
static DWORD globalkey = TLS_OUT_OF_INDEXES;
|
||||
|
||||
#endif /* HAVE_COMPILER_TLS */
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_WIN32_THREADS */
|
||||
|
||||
#ifdef LIBXML_THREAD_ENABLED
|
||||
static void
|
||||
xmlFreeGlobalState(void *state);
|
||||
#endif
|
||||
|
||||
#endif /* LIBXML_THREAD_ENABLED */
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
@ -522,7 +523,7 @@ void xmlInitGlobalsInternal(void) {
|
||||
#endif /* XML_PTHREAD_WEAK */
|
||||
pthread_key_create(&globalkey, xmlFreeGlobalState);
|
||||
#elif defined(HAVE_WIN32_THREADS)
|
||||
#if !defined(HAVE_COMPILER_TLS)
|
||||
#ifndef XML_THREAD_LOCAL
|
||||
globalkey = TlsAlloc();
|
||||
#endif
|
||||
#endif
|
||||
@ -556,7 +557,7 @@ void xmlCleanupGlobalsInternal(void) {
|
||||
#endif /* XML_PTHREAD_WEAK */
|
||||
pthread_key_delete(globalkey);
|
||||
#elif defined(HAVE_WIN32_THREADS)
|
||||
#if !defined(HAVE_COMPILER_TLS)
|
||||
#ifndef XML_THREAD_LOCAL
|
||||
if (globalkey != TLS_OUT_OF_INDEXES) {
|
||||
TlsFree(globalkey);
|
||||
globalkey = TLS_OUT_OF_INDEXES;
|
||||
@ -602,7 +603,7 @@ xmlFreeGlobalState(void *state)
|
||||
|
||||
/* free any memory allocated in the thread's xmlLastError */
|
||||
xmlResetError(&(gs->gs_xmlLastError));
|
||||
#if !defined(HAVE_WIN32_THREADS) || !defined(HAVE_COMPILER_TLS)
|
||||
#ifndef XML_THREAD_LOCAL
|
||||
free(state);
|
||||
#endif
|
||||
}
|
||||
@ -699,15 +700,18 @@ xmlInitGlobalState(xmlGlobalStatePtr gs) {
|
||||
#ifdef HAVE_POSIX_THREADS
|
||||
pthread_setspecific(globalkey, gs);
|
||||
#elif defined HAVE_WIN32_THREADS
|
||||
#ifndef HAVE_COMPILER_TLS
|
||||
#ifndef XML_THREAD_LOCAL
|
||||
TlsSetValue(globalkey, gs);
|
||||
#endif
|
||||
#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
|
||||
xmlRegisterGlobalStateDtor(gs);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
gs->initialized = 1;
|
||||
}
|
||||
|
||||
#ifndef XML_THREAD_LOCAL
|
||||
/**
|
||||
* xmlNewGlobalState:
|
||||
*
|
||||
@ -730,32 +734,29 @@ xmlNewGlobalState(void)
|
||||
xmlInitGlobalState(gs);
|
||||
return (gs);
|
||||
}
|
||||
#endif
|
||||
|
||||
static xmlGlobalStatePtr
|
||||
xmlGetThreadLocalStorage(void) {
|
||||
#ifdef HAVE_POSIX_THREADS
|
||||
xmlGlobalState *gs;
|
||||
|
||||
#ifdef XML_THREAD_LOCAL
|
||||
gs = &globalState;
|
||||
if (gs->initialized == 0)
|
||||
xmlInitGlobalState(gs);
|
||||
#elif defined(HAVE_POSIX_THREADS)
|
||||
gs = (xmlGlobalState *) pthread_getspecific(globalkey);
|
||||
if (gs == NULL)
|
||||
gs = xmlNewGlobalState();
|
||||
return (gs);
|
||||
#elif defined HAVE_WIN32_THREADS
|
||||
#if defined(HAVE_COMPILER_TLS)
|
||||
if (!tlstate_inited) {
|
||||
tlstate_inited = 1;
|
||||
xmlInitGlobalState(&tlstate);
|
||||
}
|
||||
return &tlstate;
|
||||
#else /* HAVE_COMPILER_TLS */
|
||||
xmlGlobalState *gs;
|
||||
#elif defined(HAVE_WIN32_THREADS)
|
||||
gs = (xmlGlobalState *) TlsGetValue(globalkey);
|
||||
if (gs == NULL)
|
||||
gs = xmlNewGlobalState();
|
||||
return (gs);
|
||||
#endif /* HAVE_COMPILER_TLS */
|
||||
#else
|
||||
return (NULL);
|
||||
gs = NULL;
|
||||
#endif
|
||||
|
||||
return(gs);
|
||||
}
|
||||
#endif /* LIBXML_THREAD_ENABLED */
|
||||
|
||||
@ -779,7 +780,7 @@ xmlGetThreadLocalStorage(void) {
|
||||
*/
|
||||
int
|
||||
xmlCheckThreadLocalStorage(void) {
|
||||
#ifdef LIBXML_THREAD_ENABLED
|
||||
#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_THREAD_LOCAL_STORAGE)
|
||||
if ((!xmlIsMainThread()) && (xmlGetThreadLocalStorage() == NULL))
|
||||
return(-1);
|
||||
#endif
|
||||
@ -821,6 +822,9 @@ DllMain(ATTRIBUTE_UNUSED HINSTANCE hinstDLL, DWORD fdwReason,
|
||||
{
|
||||
switch (fdwReason) {
|
||||
case DLL_THREAD_DETACH:
|
||||
#ifdef XML_THREAD_LOCAL
|
||||
xmlFreeGlobalState(&globalState);
|
||||
#else
|
||||
if (globalkey != TLS_OUT_OF_INDEXES) {
|
||||
xmlGlobalState *globalval;
|
||||
|
||||
@ -830,6 +834,7 @@ DllMain(ATTRIBUTE_UNUSED HINSTANCE hinstDLL, DWORD fdwReason,
|
||||
TlsSetValue(globalkey, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -57,8 +57,8 @@ CFLAGS = $(CFLAGS) -D_REENTRANT -tWM
|
||||
!if "$(DYNRUNTIME)" == "1"
|
||||
CFLAGS = $(CFLAGS) -tWR
|
||||
!endif
|
||||
!if "$(WITH_THREADS)" == "yes" || "$(WITH_THREADS)" == "ctls"
|
||||
CFLAGS = $(CFLAGS) -DHAVE_COMPILER_TLS
|
||||
!if "$(WITH_THREADS)" == "ctls"
|
||||
CFLAGS = $(CFLAGS) "-DXML_THREAD_LOCAL=__declspec(thread)"
|
||||
!else if "$(WITH_THREADS)" == "posix"
|
||||
CFLAGS = $(CFLAGS) -DHAVE_PTHREAD_H
|
||||
!endif
|
||||
|
@ -45,11 +45,8 @@ CFLAGS += -I$(XML_SRCDIR) -I$(XML_SRCDIR)/include -I$(INCPREFIX) $(INCLUDE)
|
||||
ifneq ($(WITH_THREADS),no)
|
||||
CFLAGS += -D_REENTRANT
|
||||
endif
|
||||
ifeq ($(WITH_THREADS),yes)
|
||||
CFLAGS += -DHAVE_COMPILER_TLS
|
||||
endif
|
||||
ifeq ($(WITH_THREADS),ctls)
|
||||
CFLAGS += -DHAVE_COMPILER_TLS
|
||||
CFLAGS += "-DXML_THREAD_LOCAL=__declspec(thread)"
|
||||
endif
|
||||
ifeq ($(WITH_THREADS),posix)
|
||||
CFLAGS += -DHAVE_PTHREAD_H
|
||||
|
@ -48,8 +48,8 @@ CFLAGS = $(CFLAGS) /I$(XML_SRCDIR) /I$(XML_SRCDIR)\include /I$(INCPREFIX)
|
||||
!if "$(WITH_THREADS)" != "no"
|
||||
CFLAGS = $(CFLAGS) /D "_REENTRANT"
|
||||
!endif
|
||||
!if "$(WITH_THREADS)" == "yes" || "$(WITH_THREADS)" == "ctls"
|
||||
CFLAGS = $(CFLAGS) /D "HAVE_COMPILER_TLS"
|
||||
!if "$(WITH_THREADS)" == "ctls"
|
||||
CFLAGS = $(CFLAGS) /D "XML_THREAD_LOCAL=__declspec(thread)"
|
||||
!else if "$(WITH_THREADS)" == "posix"
|
||||
CFLAGS = $(CFLAGS) /D "HAVE_PTHREAD_H"
|
||||
!endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user