mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-20 16:43:05 +03:00
applied Serguei Narojnyi's patch to add native thread support on the Win32
* threads.c: applied Serguei Narojnyi's patch to add native thread support on the Win32 platform * testThreadsWin32.c Makefile.am: added the test program also from Serguei, Win32 specific * include/win32config.h include/libxml/xmlwin32version.h.in: added patch from Igor for the Windows thread specific defines. Daniel
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
Sun Jan 13 14:23:21 CET 2002 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
|
* threads.c: applied Serguei Narojnyi's patch to add native
|
||||||
|
thread support on the Win32 platform
|
||||||
|
* testThreadsWin32.c Makefile.am: added the test program also
|
||||||
|
from Serguei, Win32 specific
|
||||||
|
* include/win32config.h include/libxml/xmlwin32version.h.in:
|
||||||
|
added patch from Igor for the Windows thread specific defines.
|
||||||
|
|
||||||
Wed Jan 9 12:50:39 CET 2002 Daniel Veillard <daniel@veillard.com>
|
Wed Jan 9 12:50:39 CET 2002 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
* entities.c: Anthony Jones pointed a bug in xmlCopyEntity()
|
* entities.c: Anthony Jones pointed a bug in xmlCopyEntity()
|
||||||
|
@ -569,7 +569,8 @@ EXTRA_DIST = xml2-config.in xml2Conf.sh.in libxml.spec.in libxml.spec \
|
|||||||
example/Makefile.am example/gjobread.c example/gjobs.xml \
|
example/Makefile.am example/gjobread.c example/gjobs.xml \
|
||||||
$(man_MANS) libxml-2.0.pc.in \
|
$(man_MANS) libxml-2.0.pc.in \
|
||||||
trionan.c trionan.h strio.c strio.h trio.c trio.h \
|
trionan.c trionan.h strio.c strio.h trio.c trio.h \
|
||||||
triop.h triodef.h libxml.h
|
triop.h triodef.h libxml.h \
|
||||||
|
testThreadsWin32.c
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
pkgconfig_DATA = libxml-2.0.pc
|
pkgconfig_DATA = libxml-2.0.pc
|
||||||
|
@ -35,7 +35,7 @@ sgml:
|
|||||||
gtkdoc-mkdb --module=libxml --source-dir=$(DOC_SOURCE_DIR)
|
gtkdoc-mkdb --module=libxml --source-dir=$(DOC_SOURCE_DIR)
|
||||||
|
|
||||||
html:
|
html:
|
||||||
if ! test -d html ; then mkdir html ; fi
|
if test -n -d html ; then mkdir html ; fi
|
||||||
-cd html && gtkdoc-mkhtml libxml ../$(DOC_MAIN_SGML_FILE)
|
-cd html && gtkdoc-mkhtml libxml ../$(DOC_MAIN_SGML_FILE)
|
||||||
|
|
||||||
clean-local:
|
clean-local:
|
||||||
|
@ -67,6 +67,15 @@ extern void xmlCheckVersion(int version);
|
|||||||
#define WITHOUT_TRIO
|
#define WITHOUT_TRIO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LIBXML_THREADS_ENABLED:
|
||||||
|
*
|
||||||
|
* Whether the thread support is configured in
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
#define LIBXML_THREAD_ENABLED
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LIBXML_FTP_ENABLED:
|
* LIBXML_FTP_ENABLED:
|
||||||
*
|
*
|
||||||
|
@ -67,6 +67,15 @@ extern void xmlCheckVersion(int version);
|
|||||||
#define WITHOUT_TRIO
|
#define WITHOUT_TRIO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LIBXML_THREADS_ENABLED:
|
||||||
|
*
|
||||||
|
* Whether the thread support is configured in
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
#define LIBXML_THREAD_ENABLED
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LIBXML_FTP_ENABLED:
|
* LIBXML_FTP_ENABLED:
|
||||||
*
|
*
|
||||||
|
@ -144,5 +144,12 @@ static int isnan (double d) {
|
|||||||
#define ATTRIBUTE_UNUSED
|
#define ATTRIBUTE_UNUSED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Define this if you want to use Windows native thread implementation.
|
||||||
|
Undefine it if you wish to use another, pthreads for example. Note
|
||||||
|
that this alone does not enable threads, just specifies the
|
||||||
|
threading model. Threading support is activated in xmlversion.h by
|
||||||
|
defining LIBXML_THREAD_ENABLE. */
|
||||||
|
#define HAVE_WIN32_THREADS
|
||||||
|
|
||||||
#endif /* __LIBXML_WIN32_CONFIG__ */
|
#endif /* __LIBXML_WIN32_CONFIG__ */
|
||||||
|
|
||||||
|
146
testThreadsWin32.c
Normal file
146
testThreadsWin32.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "libxml.h"
|
||||||
|
|
||||||
|
#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
|
||||||
|
#include <libxml/globals.h>
|
||||||
|
#include <libxml/threads.h>
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
#include <libxml/catalog.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define MAX_ARGC 20
|
||||||
|
#define TEST_REPEAT_COUNT 500
|
||||||
|
|
||||||
|
static HANDLE tid[MAX_ARGC];
|
||||||
|
|
||||||
|
static const char *catalog = "test/threads/complex.xml";
|
||||||
|
static char *testfiles[] = {
|
||||||
|
"test/threads/abc.xml",
|
||||||
|
"test/threads/acb.xml",
|
||||||
|
"test/threads/bac.xml",
|
||||||
|
"test/threads/bca.xml",
|
||||||
|
"test/threads/cab.xml",
|
||||||
|
"test/threads/cba.xml",
|
||||||
|
"test/threads/invalid.xml",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *Okay = "OK";
|
||||||
|
const char *Failed = "Failed";
|
||||||
|
|
||||||
|
#ifndef xmlDoValidityCheckingDefaultValue
|
||||||
|
#error xmlDoValidityCheckingDefaultValue is not a macro
|
||||||
|
#endif
|
||||||
|
#ifndef xmlGenericErrorContext
|
||||||
|
#error xmlGenericErrorContext is not a macro
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static DWORD WINAPI
|
||||||
|
thread_specific_data(void *private_data)
|
||||||
|
{
|
||||||
|
xmlDocPtr myDoc;
|
||||||
|
const char *filename = (const char *) private_data;
|
||||||
|
int okay = 1;
|
||||||
|
|
||||||
|
if (!strcmp(filename, "test/threads/invalid.xml")) {
|
||||||
|
xmlDoValidityCheckingDefaultValue = 0;
|
||||||
|
xmlGenericErrorContext = stdout;
|
||||||
|
} else {
|
||||||
|
xmlDoValidityCheckingDefaultValue = 1;
|
||||||
|
xmlGenericErrorContext = stderr;
|
||||||
|
}
|
||||||
|
myDoc = xmlParseFile(filename);
|
||||||
|
if (myDoc) {
|
||||||
|
xmlFreeDoc(myDoc);
|
||||||
|
} else {
|
||||||
|
printf("parse failed\n");
|
||||||
|
okay = 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(filename, "test/threads/invalid.xml")) {
|
||||||
|
if (xmlDoValidityCheckingDefaultValue != 0) {
|
||||||
|
printf("ValidityCheckingDefaultValue override failed\n");
|
||||||
|
okay = 0;
|
||||||
|
}
|
||||||
|
if (xmlGenericErrorContext != stdout) {
|
||||||
|
printf("xmlGenericErrorContext override failed\n");
|
||||||
|
okay = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (xmlDoValidityCheckingDefaultValue != 1) {
|
||||||
|
printf("ValidityCheckingDefaultValue override failed\n");
|
||||||
|
okay = 0;
|
||||||
|
}
|
||||||
|
if (xmlGenericErrorContext != stderr) {
|
||||||
|
printf("xmlGenericErrorContext override failed\n");
|
||||||
|
okay = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (okay == 0)
|
||||||
|
return ((DWORD) Failed);
|
||||||
|
return ((DWORD) Okay);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
unsigned int i, repeat;
|
||||||
|
unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
|
||||||
|
DWORD results[MAX_ARGC];
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
xmlInitParser();
|
||||||
|
for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++)
|
||||||
|
{
|
||||||
|
xmlLoadCatalog(catalog);
|
||||||
|
|
||||||
|
for (i = 0; i < num_threads; i++)
|
||||||
|
{
|
||||||
|
results[i] = 0;
|
||||||
|
tid[i] = (HANDLE) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_threads; i++)
|
||||||
|
{
|
||||||
|
DWORD useless;
|
||||||
|
tid[i] = CreateThread (NULL, 0, thread_specific_data, testfiles[i], 0, &useless);
|
||||||
|
if (tid[i] == NULL)
|
||||||
|
{
|
||||||
|
perror("CreateThread");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WaitForMultipleObjects (num_threads, tid, TRUE, INFINITE) == WAIT_FAILED) perror ("WaitForMultipleObjects failed");
|
||||||
|
|
||||||
|
for (i = 0; i < num_threads; i++)
|
||||||
|
{
|
||||||
|
ret = GetExitCodeThread (tid[i], &results[i]);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
perror("GetExitCodeThread");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
CloseHandle (tid[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlCatalogCleanup();
|
||||||
|
for (i = 0; i < num_threads; i++)
|
||||||
|
if (results[i] != (DWORD) Okay) printf("Thread %d handling %s failed\n", i, testfiles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlCleanupParser();
|
||||||
|
xmlMemoryDump();
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !LIBXML_THREADS_ENABLED */
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
fprintf(stderr, "libxml was not compiled with thread or catalog support\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
#endif
|
104
threads.c
104
threads.c
@ -26,6 +26,12 @@
|
|||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_WIN32_THREADS
|
||||||
|
#include <windows.h>
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <process.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SOLARIS)
|
#if defined(SOLARIS)
|
||||||
#include <note.h>
|
#include <note.h>
|
||||||
@ -45,6 +51,8 @@
|
|||||||
struct _xmlMutex {
|
struct _xmlMutex {
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_mutex_t lock;
|
pthread_mutex_t lock;
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
HANDLE mutex;
|
||||||
#else
|
#else
|
||||||
int empty;
|
int empty;
|
||||||
#endif
|
#endif
|
||||||
@ -60,6 +68,9 @@ struct _xmlRMutex {
|
|||||||
unsigned int waiters;
|
unsigned int waiters;
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
pthread_cond_t cv;
|
pthread_cond_t cv;
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
CRITICAL_SECTION cs;
|
||||||
|
unsigned int count;
|
||||||
#else
|
#else
|
||||||
int empty;
|
int empty;
|
||||||
#endif
|
#endif
|
||||||
@ -74,7 +85,16 @@ struct _xmlRMutex {
|
|||||||
static pthread_key_t globalkey;
|
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;
|
||||||
#endif
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
static __declspec (thread) xmlGlobalState tlstate;
|
||||||
|
static __declspec (thread) int tlstate_inited = 0;
|
||||||
|
#else
|
||||||
|
static DWORD globalkey;
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
static DWORD mainthread;
|
||||||
|
static int run_once_init = 1;
|
||||||
|
#endif /* HAVE_WIN32_THREADS */
|
||||||
static xmlRMutexPtr xmlLibraryLock = NULL;
|
static xmlRMutexPtr xmlLibraryLock = NULL;
|
||||||
static void xmlOnceInit(void);
|
static void xmlOnceInit(void);
|
||||||
|
|
||||||
@ -95,6 +115,8 @@ xmlNewMutex(void)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
#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
|
||||||
|
tok->mutex = CreateMutex (NULL, FALSE, NULL);
|
||||||
#endif
|
#endif
|
||||||
return (tok);
|
return (tok);
|
||||||
}
|
}
|
||||||
@ -111,6 +133,8 @@ 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
|
||||||
|
CloseHandle (tok->mutex);
|
||||||
#endif
|
#endif
|
||||||
free(tok);
|
free(tok);
|
||||||
}
|
}
|
||||||
@ -126,6 +150,8 @@ xmlMutexLock(xmlMutexPtr tok)
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_mutex_lock(&tok->lock);
|
pthread_mutex_lock(&tok->lock);
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
WaitForSingleObject (tok->mutex, INFINITE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -141,6 +167,8 @@ xmlMutexUnlock(xmlMutexPtr tok)
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_mutex_unlock(&tok->lock);
|
pthread_mutex_unlock(&tok->lock);
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
ReleaseMutex (tok->mutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +193,9 @@ xmlNewRMutex(void)
|
|||||||
pthread_mutex_init(&tok->lock, NULL);
|
pthread_mutex_init(&tok->lock, NULL);
|
||||||
tok->held = 0;
|
tok->held = 0;
|
||||||
tok->waiters = 0;
|
tok->waiters = 0;
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
InitializeCriticalSection (&tok->cs);
|
||||||
|
tok->count = 0;
|
||||||
#endif
|
#endif
|
||||||
return (tok);
|
return (tok);
|
||||||
}
|
}
|
||||||
@ -181,6 +212,8 @@ xmlFreeRMutex(xmlRMutexPtr tok)
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
pthread_mutex_destroy(&tok->lock);
|
pthread_mutex_destroy(&tok->lock);
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
DeleteCriticalSection (&tok->cs);
|
||||||
#endif
|
#endif
|
||||||
free(tok);
|
free(tok);
|
||||||
}
|
}
|
||||||
@ -211,6 +244,9 @@ xmlRMutexLock(xmlRMutexPtr tok)
|
|||||||
tok->tid = pthread_self();
|
tok->tid = pthread_self();
|
||||||
tok->held = 1;
|
tok->held = 1;
|
||||||
pthread_mutex_unlock(&tok->lock);
|
pthread_mutex_unlock(&tok->lock);
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
EnterCriticalSection (&tok->cs);
|
||||||
|
++tok->count;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,6 +268,8 @@ xmlRMutexUnlock(xmlRMutexPtr tok)
|
|||||||
tok->tid = 0;
|
tok->tid = 0;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&tok->lock);
|
pthread_mutex_unlock(&tok->lock);
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
if (!--tok->count) LeaveCriticalSection (&tok->cs);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +280,7 @@ xmlRMutexUnlock(xmlRMutexPtr tok)
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
#ifdef LIBXML_THREAD_ENABLED
|
#ifdef LIBXML_THREAD_ENABLED
|
||||||
|
#ifndef _MSC_VER
|
||||||
/**
|
/**
|
||||||
* xmlFreeGlobalState:
|
* xmlFreeGlobalState:
|
||||||
* @state: a thread global state
|
* @state: a thread global state
|
||||||
@ -277,6 +316,7 @@ xmlNewGlobalState(void)
|
|||||||
xmlInitializeGlobalState(gs);
|
xmlInitializeGlobalState(gs);
|
||||||
return (gs);
|
return (gs);
|
||||||
}
|
}
|
||||||
|
#endif /* _MSC_VER */
|
||||||
#endif /* LIBXML_THREAD_ENABLED */
|
#endif /* LIBXML_THREAD_ENABLED */
|
||||||
|
|
||||||
|
|
||||||
@ -287,6 +327,27 @@ xmlNewGlobalState(void)
|
|||||||
*
|
*
|
||||||
* Returns the thread global state or NULL in case of error
|
* Returns the thread global state or NULL in case of error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_WIN32_THREADS
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
typedef struct _xmlGlobalStateCleanupHelperParams
|
||||||
|
{
|
||||||
|
HANDLE thread;
|
||||||
|
void *memory;
|
||||||
|
} xmlGlobalStateCleanupHelperParams;
|
||||||
|
|
||||||
|
void __cdecl xmlGlobalStateCleanupHelper (void *p)
|
||||||
|
{
|
||||||
|
xmlGlobalStateCleanupHelperParams *params = (xmlGlobalStateCleanupHelperParams *) p;
|
||||||
|
WaitForSingleObject (params->thread, INFINITE);
|
||||||
|
CloseHandle (params->thread);
|
||||||
|
xmlFreeGlobalState (params->memory);
|
||||||
|
free (params);
|
||||||
|
_endthread ();
|
||||||
|
}
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
#endif /* HAVE_WIN32_THREADS */
|
||||||
|
|
||||||
xmlGlobalStatePtr
|
xmlGlobalStatePtr
|
||||||
xmlGetGlobalState(void)
|
xmlGetGlobalState(void)
|
||||||
{
|
{
|
||||||
@ -303,12 +364,40 @@ xmlGetGlobalState(void)
|
|||||||
return (tsd);
|
return (tsd);
|
||||||
}
|
}
|
||||||
return (globalval);
|
return (globalval);
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
if (!tlstate_inited)
|
||||||
|
{
|
||||||
|
tlstate_inited = 1;
|
||||||
|
xmlInitializeGlobalState (&tlstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &tlstate;
|
||||||
|
#else /* !_MSC_VER */
|
||||||
|
xmlGlobalState *globalval;
|
||||||
|
|
||||||
|
if (run_once_init) { run_once_init = 0; 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);
|
||||||
|
|
||||||
|
return (tsd);
|
||||||
|
}
|
||||||
|
return (globalval);
|
||||||
|
#endif /* _MSC_VER */
|
||||||
#else
|
#else
|
||||||
return(NULL);
|
return(NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
* Library wide thread interfaces *
|
* Library wide thread interfaces *
|
||||||
@ -327,6 +416,8 @@ xmlGetThreadId(void)
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
return((int) pthread_self());
|
return((int) pthread_self());
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
return GetCurrentThreadId ();
|
||||||
#else
|
#else
|
||||||
return((int) 0);
|
return((int) 0);
|
||||||
#endif
|
#endif
|
||||||
@ -344,6 +435,8 @@ 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
|
||||||
|
if (run_once_init) { run_once_init = 0; xmlOnceInit (); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_THREADS
|
#ifdef DEBUG_THREADS
|
||||||
@ -351,6 +444,8 @@ xmlIsMainThread(void)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
return(mainthread == pthread_self());
|
return(mainthread == pthread_self());
|
||||||
|
#elif defined HAVE_WIN32_THREADS
|
||||||
|
return (mainthread == GetCurrentThreadId ());
|
||||||
#else
|
#else
|
||||||
return(1);
|
return(1);
|
||||||
#endif
|
#endif
|
||||||
@ -428,5 +523,10 @@ 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
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
globalkey = TlsAlloc ();
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
mainthread = GetCurrentThreadId ();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user