mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-10-24 13:33:01 +03:00
globals: Introduce xmlCheckThreadLocalStorage
Checks whether (emulated) thread-local storage could be allocated.
This commit is contained in:
25
globals.c
25
globals.c
@@ -806,6 +806,31 @@ xmlNewGlobalState(void)
|
|||||||
}
|
}
|
||||||
#endif /* LIBXML_THREAD_ENABLED */
|
#endif /* LIBXML_THREAD_ENABLED */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlCheckThreadLocalStorage:
|
||||||
|
*
|
||||||
|
* Check whether thread-local storage could be allocated.
|
||||||
|
*
|
||||||
|
* In multithreaded environments, this function should be called once
|
||||||
|
* in each thread before calling other library functions to make sure
|
||||||
|
* that thread-local storage was allocated properly.
|
||||||
|
*
|
||||||
|
* Returns 0 on success or -1 if a memory allocation failed. A failed
|
||||||
|
* allocation signals a typically fatal and irrecoverable out-of-memory
|
||||||
|
* situation. Don't call any library functions in this case.
|
||||||
|
*
|
||||||
|
* This function never fails for the "main" thread which is the first
|
||||||
|
* thread calling xmlInitParser.
|
||||||
|
*
|
||||||
|
* Available since v2.12.0.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlCheckThreadLocalStorage(void) {
|
||||||
|
if (IS_MAIN_THREAD)
|
||||||
|
return(0);
|
||||||
|
return((xmlGetGlobalState() == NULL) ? -1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlGetGlobalState:
|
* xmlGetGlobalState:
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ typedef void (*xmlDeregisterNodeFunc) (xmlNodePtr node);
|
|||||||
typedef struct _xmlGlobalState xmlGlobalState;
|
typedef struct _xmlGlobalState xmlGlobalState;
|
||||||
typedef xmlGlobalState *xmlGlobalStatePtr;
|
typedef xmlGlobalState *xmlGlobalStatePtr;
|
||||||
|
|
||||||
|
XMLPUBFUN int xmlCheckThreadLocalStorage(void);
|
||||||
XML_DEPRECATED
|
XML_DEPRECATED
|
||||||
XMLPUBFUN void xmlInitializeGlobalState(xmlGlobalStatePtr gs);
|
XMLPUBFUN void xmlInitializeGlobalState(xmlGlobalStatePtr gs);
|
||||||
XML_DEPRECATED
|
XML_DEPRECATED
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
|
|
||||||
#include <libxml/globals.h>
|
|
||||||
#include <libxml/threads.h>
|
|
||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
|
#include <libxml/threads.h>
|
||||||
|
#include <libxml/globals.h>
|
||||||
|
|
||||||
|
#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
|
||||||
#include <libxml/catalog.h>
|
#include <libxml/catalog.h>
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
@@ -57,6 +58,12 @@ thread_specific_data(void *private_data)
|
|||||||
const char *filename = params->filename;
|
const char *filename = params->filename;
|
||||||
int okay = 1;
|
int okay = 1;
|
||||||
|
|
||||||
|
if (xmlCheckThreadLocalStorage() != 0) {
|
||||||
|
printf("xmlCheckThreadLocalStorage failed\n");
|
||||||
|
params->okay = 0;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(filename, "test/threads/invalid.xml")) {
|
if (!strcmp(filename, "test/threads/invalid.xml")) {
|
||||||
xmlDoValidityCheckingDefaultValue = 0;
|
xmlDoValidityCheckingDefaultValue = 0;
|
||||||
xmlGenericErrorContext = stdout;
|
xmlGenericErrorContext = stdout;
|
||||||
@@ -98,17 +105,39 @@ thread_specific_data(void *private_data)
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef _WIN32
|
||||||
|
static DWORD WINAPI
|
||||||
|
win32_thread_specific_data(void *private_data)
|
||||||
|
{
|
||||||
|
thread_specific_data(private_data);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* LIBXML_THREADS_ENABLED */
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
unsigned int i, repeat;
|
unsigned int repeat;
|
||||||
int ret;
|
int status = 0;
|
||||||
|
|
||||||
|
(void) repeat;
|
||||||
|
|
||||||
xmlInitParser();
|
xmlInitParser();
|
||||||
|
|
||||||
|
if (xmlCheckThreadLocalStorage() != 0) {
|
||||||
|
printf("xmlCheckThreadLocalStorage failed for main thread\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
|
||||||
for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++) {
|
for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++) {
|
||||||
|
unsigned int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
xmlLoadCatalog(catalog);
|
xmlLoadCatalog(catalog);
|
||||||
|
|
||||||
|
#ifdef HAVE_PTHREAD_H
|
||||||
memset(tid, 0xff, sizeof(*tid)*num_threads);
|
memset(tid, 0xff, sizeof(*tid)*num_threads);
|
||||||
|
|
||||||
for (i = 0; i < num_threads; i++) {
|
for (i = 0; i < num_threads; i++) {
|
||||||
@@ -127,35 +156,7 @@ main(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlCatalogCleanup();
|
|
||||||
for (i = 0; i < num_threads; i++)
|
|
||||||
if (threadParams[i].okay == 0)
|
|
||||||
printf("Thread %d handling %s failed\n", i,
|
|
||||||
threadParams[i].filename);
|
|
||||||
}
|
|
||||||
xmlCleanupParser();
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
static DWORD WINAPI
|
|
||||||
win32_thread_specific_data(void *private_data)
|
|
||||||
{
|
|
||||||
thread_specific_data(private_data);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(void)
|
|
||||||
{
|
|
||||||
unsigned int i, repeat;
|
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
xmlInitParser();
|
|
||||||
for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++)
|
|
||||||
{
|
|
||||||
xmlLoadCatalog(catalog);
|
|
||||||
|
|
||||||
for (i = 0; i < num_threads; i++)
|
for (i = 0; i < num_threads; i++)
|
||||||
{
|
{
|
||||||
tid[i] = (HANDLE) -1;
|
tid[i] = (HANDLE) -1;
|
||||||
@@ -187,26 +188,22 @@ main(void)
|
|||||||
}
|
}
|
||||||
CloseHandle (tid[i]);
|
CloseHandle (tid[i]);
|
||||||
}
|
}
|
||||||
|
#endif /* pthreads */
|
||||||
|
|
||||||
xmlCatalogCleanup();
|
xmlCatalogCleanup();
|
||||||
for (i = 0; i < num_threads; i++) {
|
|
||||||
if (threadParams[i].okay == 0)
|
for (i = 0; i < num_threads; i++) {
|
||||||
printf("Thread %d handling %s failed\n", i,
|
if (threadParams[i].okay == 0) {
|
||||||
threadParams[i].filename);
|
printf("Thread %d handling %s failed\n", i,
|
||||||
|
threadParams[i].filename);
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* LIBXML_THREADS_ENABLED */
|
||||||
|
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
|
|
||||||
return (0);
|
return (status);
|
||||||
}
|
}
|
||||||
#endif /* pthreads */
|
|
||||||
|
|
||||||
#else /* !LIBXML_THREADS_ENABLED */
|
|
||||||
int
|
|
||||||
main(void)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "libxml was not compiled with thread or catalog support\n");
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|||||||
Reference in New Issue
Block a user