2023-09-21 01:44:50 +03:00
# include "config.h"
2001-10-17 15:30:37 +04:00
# include <stdlib.h>
2001-10-17 19:58:35 +04:00
# include <stdio.h>
2001-10-17 15:30:37 +04:00
# include <libxml/parser.h>
2023-09-18 20:53:31 +03:00
# include <libxml/threads.h>
# if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
2001-10-17 15:30:37 +04:00
# include <libxml/catalog.h>
2003-10-29 16:39:15 +03:00
# ifdef HAVE_PTHREAD_H
2001-10-17 15:30:37 +04:00
# include <pthread.h>
2022-09-04 02:49:41 +03:00
# elif defined(_WIN32)
2018-01-23 19:33:42 +03:00
# include <windows.h>
2003-10-29 16:39:15 +03:00
# endif
2001-10-17 15:30:37 +04:00
# include <string.h>
# include <assert.h>
# define MAX_ARGC 20
2018-01-23 19:33:42 +03:00
# define TEST_REPEAT_COUNT 500
2003-10-29 16:39:15 +03:00
# ifdef HAVE_PTHREAD_H
2001-10-17 15:30:37 +04:00
static pthread_t tid [ MAX_ARGC ] ;
2022-09-04 02:49:41 +03:00
# elif defined(_WIN32)
2018-01-23 19:33:42 +03:00
static HANDLE tid [ MAX_ARGC ] ;
2003-10-29 16:39:15 +03:00
# endif
2001-10-17 15:30:37 +04:00
2018-01-23 19:33:42 +03:00
typedef struct {
const char * filename ;
int okay ;
} xmlThreadParams ;
2001-10-17 15:30:37 +04:00
static const char * catalog = " test/threads/complex.xml " ;
2018-01-23 19:33:42 +03:00
static xmlThreadParams threadParams [ ] = {
{ " test/threads/abc.xml " , 0 } ,
{ " test/threads/acb.xml " , 0 } ,
{ " test/threads/bac.xml " , 0 } ,
{ " test/threads/bca.xml " , 0 } ,
{ " test/threads/cab.xml " , 0 } ,
{ " test/threads/cba.xml " , 0 } ,
{ " test/threads/invalid.xml " , 0 }
2001-10-17 15:30:37 +04:00
} ;
2018-01-23 19:33:42 +03:00
static const unsigned int num_threads = sizeof ( threadParams ) /
sizeof ( threadParams [ 0 ] ) ;
2001-10-17 19:58:35 +04:00
2001-10-17 15:30:37 +04:00
static void *
thread_specific_data ( void * private_data )
{
xmlDocPtr myDoc ;
2018-01-23 19:33:42 +03:00
xmlThreadParams * params = ( xmlThreadParams * ) private_data ;
const char * filename = params - > filename ;
2001-10-17 19:58:35 +04:00
int okay = 1 ;
2023-09-20 16:49:03 +03:00
int options = 0 ;
2001-10-17 15:30:37 +04:00
2023-09-18 20:53:31 +03:00
if ( xmlCheckThreadLocalStorage ( ) ! = 0 ) {
printf ( " xmlCheckThreadLocalStorage failed \n " ) ;
params - > okay = 0 ;
return ( NULL ) ;
}
2023-09-20 16:49:03 +03:00
if ( strcmp ( filename , " test/threads/invalid.xml " ) ! = 0 ) {
options | = XML_PARSE_DTDVALID ;
2001-10-17 15:30:37 +04:00
}
2023-09-20 16:49:03 +03:00
myDoc = xmlReadFile ( filename , NULL , options ) ;
2001-10-17 15:30:37 +04:00
if ( myDoc ) {
xmlFreeDoc ( myDoc ) ;
2001-10-17 19:58:35 +04:00
} else {
2001-10-17 15:30:37 +04:00
printf ( " parse failed \n " ) ;
2001-10-17 19:58:35 +04:00
okay = 0 ;
}
2018-01-23 19:33:42 +03:00
params - > okay = okay ;
return ( NULL ) ;
2001-10-17 15:30:37 +04:00
}
2023-09-18 20:53:31 +03:00
# ifdef _WIN32
static DWORD WINAPI
win32_thread_specific_data ( void * private_data )
{
thread_specific_data ( private_data ) ;
return ( 0 ) ;
}
# endif
# endif /* LIBXML_THREADS_ENABLED */
2001-10-17 15:30:37 +04:00
int
2003-08-06 08:43:55 +04:00
main ( void )
2001-10-17 15:30:37 +04:00
{
2023-09-18 20:53:31 +03:00
unsigned int repeat ;
int status = 0 ;
( void ) repeat ;
2001-10-17 15:30:37 +04:00
xmlInitParser ( ) ;
2023-09-18 20:53:31 +03:00
if ( xmlCheckThreadLocalStorage ( ) ! = 0 ) {
printf ( " xmlCheckThreadLocalStorage failed for main thread \n " ) ;
return ( 1 ) ;
}
# if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
2018-01-23 19:33:42 +03:00
for ( repeat = 0 ; repeat < TEST_REPEAT_COUNT ; repeat + + ) {
2023-09-18 20:53:31 +03:00
unsigned int i ;
int ret ;
2001-10-17 19:58:35 +04:00
xmlLoadCatalog ( catalog ) ;
2001-10-17 15:30:37 +04:00
2023-09-18 20:53:31 +03:00
# ifdef HAVE_PTHREAD_H
2010-11-15 15:00:29 +03:00
memset ( tid , 0xff , sizeof ( * tid ) * num_threads ) ;
2001-10-17 15:30:37 +04:00
2001-10-17 19:58:35 +04:00
for ( i = 0 ; i < num_threads ; i + + ) {
2005-07-29 03:49:35 +04:00
ret = pthread_create ( & tid [ i ] , NULL , thread_specific_data ,
2018-01-23 19:33:42 +03:00
( void * ) & threadParams [ i ] ) ;
2001-10-17 19:58:35 +04:00
if ( ret ! = 0 ) {
perror ( " pthread_create " ) ;
exit ( 1 ) ;
}
}
for ( i = 0 ; i < num_threads ; i + + ) {
2018-01-23 19:33:42 +03:00
void * result ;
ret = pthread_join ( tid [ i ] , & result ) ;
2001-10-17 19:58:35 +04:00
if ( ret ! = 0 ) {
perror ( " pthread_join " ) ;
exit ( 1 ) ;
}
}
2022-09-04 02:49:41 +03:00
# elif defined(_WIN32)
2018-01-23 19:33:42 +03:00
for ( i = 0 ; i < num_threads ; i + + )
{
tid [ i ] = ( HANDLE ) - 1 ;
}
for ( i = 0 ; i < num_threads ; i + + )
{
DWORD useless ;
tid [ i ] = CreateThread ( NULL , 0 ,
win32_thread_specific_data , & threadParams [ 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 + + )
{
DWORD exitCode ;
ret = GetExitCodeThread ( tid [ i ] , & exitCode ) ;
if ( ret = = 0 )
{
perror ( " GetExitCodeThread " ) ;
exit ( 1 ) ;
}
CloseHandle ( tid [ i ] ) ;
}
2023-09-18 20:53:31 +03:00
# endif /* pthreads */
xmlCatalogCleanup ( ) ;
2018-01-23 19:33:42 +03:00
2023-09-18 20:53:31 +03:00
for ( i = 0 ; i < num_threads ; i + + ) {
if ( threadParams [ i ] . okay = = 0 ) {
printf ( " Thread %d handling %s failed \n " , i ,
threadParams [ i ] . filename ) ;
status = 1 ;
}
2018-01-23 19:33:42 +03:00
}
}
2023-09-18 20:53:31 +03:00
# endif /* LIBXML_THREADS_ENABLED */
2018-01-23 19:33:42 +03:00
xmlCleanupParser ( ) ;
2023-09-18 20:53:31 +03:00
return ( status ) ;
2018-01-23 19:33:42 +03:00
}
2001-10-17 15:30:37 +04:00