1*6777b538SAndroid Build Coastguard Worker #include "config.h"
2*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
3*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include <libxml/parser.h>
6*6777b538SAndroid Build Coastguard Worker #include <libxml/threads.h>
7*6777b538SAndroid Build Coastguard Worker
8*6777b538SAndroid Build Coastguard Worker #if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
9*6777b538SAndroid Build Coastguard Worker #include <libxml/catalog.h>
10*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_PTHREAD_H
11*6777b538SAndroid Build Coastguard Worker #include <pthread.h>
12*6777b538SAndroid Build Coastguard Worker #elif defined(_WIN32)
13*6777b538SAndroid Build Coastguard Worker #include <windows.h>
14*6777b538SAndroid Build Coastguard Worker #endif
15*6777b538SAndroid Build Coastguard Worker #include <string.h>
16*6777b538SAndroid Build Coastguard Worker #include <assert.h>
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker #define MAX_ARGC 20
19*6777b538SAndroid Build Coastguard Worker #define TEST_REPEAT_COUNT 500
20*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_PTHREAD_H
21*6777b538SAndroid Build Coastguard Worker static pthread_t tid[MAX_ARGC];
22*6777b538SAndroid Build Coastguard Worker #elif defined(_WIN32)
23*6777b538SAndroid Build Coastguard Worker static HANDLE tid[MAX_ARGC];
24*6777b538SAndroid Build Coastguard Worker #endif
25*6777b538SAndroid Build Coastguard Worker
26*6777b538SAndroid Build Coastguard Worker typedef struct {
27*6777b538SAndroid Build Coastguard Worker const char *filename;
28*6777b538SAndroid Build Coastguard Worker int okay;
29*6777b538SAndroid Build Coastguard Worker } xmlThreadParams;
30*6777b538SAndroid Build Coastguard Worker
31*6777b538SAndroid Build Coastguard Worker static const char *catalog = "test/threads/complex.xml";
32*6777b538SAndroid Build Coastguard Worker static xmlThreadParams threadParams[] = {
33*6777b538SAndroid Build Coastguard Worker { "test/threads/abc.xml", 0 },
34*6777b538SAndroid Build Coastguard Worker { "test/threads/acb.xml", 0 },
35*6777b538SAndroid Build Coastguard Worker { "test/threads/bac.xml", 0 },
36*6777b538SAndroid Build Coastguard Worker { "test/threads/bca.xml", 0 },
37*6777b538SAndroid Build Coastguard Worker { "test/threads/cab.xml", 0 },
38*6777b538SAndroid Build Coastguard Worker { "test/threads/cba.xml", 0 },
39*6777b538SAndroid Build Coastguard Worker { "test/threads/invalid.xml", 0 }
40*6777b538SAndroid Build Coastguard Worker };
41*6777b538SAndroid Build Coastguard Worker static const unsigned int num_threads = sizeof(threadParams) /
42*6777b538SAndroid Build Coastguard Worker sizeof(threadParams[0]);
43*6777b538SAndroid Build Coastguard Worker
44*6777b538SAndroid Build Coastguard Worker static void *
thread_specific_data(void * private_data)45*6777b538SAndroid Build Coastguard Worker thread_specific_data(void *private_data)
46*6777b538SAndroid Build Coastguard Worker {
47*6777b538SAndroid Build Coastguard Worker xmlDocPtr myDoc;
48*6777b538SAndroid Build Coastguard Worker xmlThreadParams *params = (xmlThreadParams *) private_data;
49*6777b538SAndroid Build Coastguard Worker const char *filename = params->filename;
50*6777b538SAndroid Build Coastguard Worker int okay = 1;
51*6777b538SAndroid Build Coastguard Worker int options = 0;
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard Worker if (xmlCheckThreadLocalStorage() != 0) {
54*6777b538SAndroid Build Coastguard Worker printf("xmlCheckThreadLocalStorage failed\n");
55*6777b538SAndroid Build Coastguard Worker params->okay = 0;
56*6777b538SAndroid Build Coastguard Worker return(NULL);
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Worker if (strcmp(filename, "test/threads/invalid.xml") != 0) {
60*6777b538SAndroid Build Coastguard Worker options |= XML_PARSE_DTDVALID;
61*6777b538SAndroid Build Coastguard Worker }
62*6777b538SAndroid Build Coastguard Worker myDoc = xmlReadFile(filename, NULL, options);
63*6777b538SAndroid Build Coastguard Worker if (myDoc) {
64*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(myDoc);
65*6777b538SAndroid Build Coastguard Worker } else {
66*6777b538SAndroid Build Coastguard Worker printf("parse failed\n");
67*6777b538SAndroid Build Coastguard Worker okay = 0;
68*6777b538SAndroid Build Coastguard Worker }
69*6777b538SAndroid Build Coastguard Worker params->okay = okay;
70*6777b538SAndroid Build Coastguard Worker return(NULL);
71*6777b538SAndroid Build Coastguard Worker }
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker #ifdef _WIN32
74*6777b538SAndroid Build Coastguard Worker static DWORD WINAPI
win32_thread_specific_data(void * private_data)75*6777b538SAndroid Build Coastguard Worker win32_thread_specific_data(void *private_data)
76*6777b538SAndroid Build Coastguard Worker {
77*6777b538SAndroid Build Coastguard Worker thread_specific_data(private_data);
78*6777b538SAndroid Build Coastguard Worker return(0);
79*6777b538SAndroid Build Coastguard Worker }
80*6777b538SAndroid Build Coastguard Worker #endif
81*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_THREADS_ENABLED */
82*6777b538SAndroid Build Coastguard Worker
83*6777b538SAndroid Build Coastguard Worker int
main(void)84*6777b538SAndroid Build Coastguard Worker main(void)
85*6777b538SAndroid Build Coastguard Worker {
86*6777b538SAndroid Build Coastguard Worker unsigned int repeat;
87*6777b538SAndroid Build Coastguard Worker int status = 0;
88*6777b538SAndroid Build Coastguard Worker
89*6777b538SAndroid Build Coastguard Worker (void) repeat;
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker xmlInitParser();
92*6777b538SAndroid Build Coastguard Worker
93*6777b538SAndroid Build Coastguard Worker if (xmlCheckThreadLocalStorage() != 0) {
94*6777b538SAndroid Build Coastguard Worker printf("xmlCheckThreadLocalStorage failed for main thread\n");
95*6777b538SAndroid Build Coastguard Worker return(1);
96*6777b538SAndroid Build Coastguard Worker }
97*6777b538SAndroid Build Coastguard Worker
98*6777b538SAndroid Build Coastguard Worker #if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
99*6777b538SAndroid Build Coastguard Worker for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++) {
100*6777b538SAndroid Build Coastguard Worker unsigned int i;
101*6777b538SAndroid Build Coastguard Worker int ret;
102*6777b538SAndroid Build Coastguard Worker
103*6777b538SAndroid Build Coastguard Worker xmlLoadCatalog(catalog);
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_PTHREAD_H
106*6777b538SAndroid Build Coastguard Worker memset(tid, 0xff, sizeof(*tid)*num_threads);
107*6777b538SAndroid Build Coastguard Worker
108*6777b538SAndroid Build Coastguard Worker for (i = 0; i < num_threads; i++) {
109*6777b538SAndroid Build Coastguard Worker ret = pthread_create(&tid[i], NULL, thread_specific_data,
110*6777b538SAndroid Build Coastguard Worker (void *) &threadParams[i]);
111*6777b538SAndroid Build Coastguard Worker if (ret != 0) {
112*6777b538SAndroid Build Coastguard Worker perror("pthread_create");
113*6777b538SAndroid Build Coastguard Worker exit(1);
114*6777b538SAndroid Build Coastguard Worker }
115*6777b538SAndroid Build Coastguard Worker }
116*6777b538SAndroid Build Coastguard Worker for (i = 0; i < num_threads; i++) {
117*6777b538SAndroid Build Coastguard Worker void *result;
118*6777b538SAndroid Build Coastguard Worker ret = pthread_join(tid[i], &result);
119*6777b538SAndroid Build Coastguard Worker if (ret != 0) {
120*6777b538SAndroid Build Coastguard Worker perror("pthread_join");
121*6777b538SAndroid Build Coastguard Worker exit(1);
122*6777b538SAndroid Build Coastguard Worker }
123*6777b538SAndroid Build Coastguard Worker }
124*6777b538SAndroid Build Coastguard Worker #elif defined(_WIN32)
125*6777b538SAndroid Build Coastguard Worker for (i = 0; i < num_threads; i++)
126*6777b538SAndroid Build Coastguard Worker {
127*6777b538SAndroid Build Coastguard Worker tid[i] = (HANDLE) -1;
128*6777b538SAndroid Build Coastguard Worker }
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard Worker for (i = 0; i < num_threads; i++)
131*6777b538SAndroid Build Coastguard Worker {
132*6777b538SAndroid Build Coastguard Worker DWORD useless;
133*6777b538SAndroid Build Coastguard Worker tid[i] = CreateThread(NULL, 0,
134*6777b538SAndroid Build Coastguard Worker win32_thread_specific_data, &threadParams[i], 0, &useless);
135*6777b538SAndroid Build Coastguard Worker if (tid[i] == NULL)
136*6777b538SAndroid Build Coastguard Worker {
137*6777b538SAndroid Build Coastguard Worker perror("CreateThread");
138*6777b538SAndroid Build Coastguard Worker exit(1);
139*6777b538SAndroid Build Coastguard Worker }
140*6777b538SAndroid Build Coastguard Worker }
141*6777b538SAndroid Build Coastguard Worker
142*6777b538SAndroid Build Coastguard Worker if (WaitForMultipleObjects (num_threads, tid, TRUE, INFINITE) == WAIT_FAILED)
143*6777b538SAndroid Build Coastguard Worker perror ("WaitForMultipleObjects failed");
144*6777b538SAndroid Build Coastguard Worker
145*6777b538SAndroid Build Coastguard Worker for (i = 0; i < num_threads; i++)
146*6777b538SAndroid Build Coastguard Worker {
147*6777b538SAndroid Build Coastguard Worker DWORD exitCode;
148*6777b538SAndroid Build Coastguard Worker ret = GetExitCodeThread (tid[i], &exitCode);
149*6777b538SAndroid Build Coastguard Worker if (ret == 0)
150*6777b538SAndroid Build Coastguard Worker {
151*6777b538SAndroid Build Coastguard Worker perror("GetExitCodeThread");
152*6777b538SAndroid Build Coastguard Worker exit(1);
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker CloseHandle (tid[i]);
155*6777b538SAndroid Build Coastguard Worker }
156*6777b538SAndroid Build Coastguard Worker #endif /* pthreads */
157*6777b538SAndroid Build Coastguard Worker
158*6777b538SAndroid Build Coastguard Worker xmlCatalogCleanup();
159*6777b538SAndroid Build Coastguard Worker
160*6777b538SAndroid Build Coastguard Worker for (i = 0; i < num_threads; i++) {
161*6777b538SAndroid Build Coastguard Worker if (threadParams[i].okay == 0) {
162*6777b538SAndroid Build Coastguard Worker printf("Thread %d handling %s failed\n", i,
163*6777b538SAndroid Build Coastguard Worker threadParams[i].filename);
164*6777b538SAndroid Build Coastguard Worker status = 1;
165*6777b538SAndroid Build Coastguard Worker }
166*6777b538SAndroid Build Coastguard Worker }
167*6777b538SAndroid Build Coastguard Worker }
168*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_THREADS_ENABLED */
169*6777b538SAndroid Build Coastguard Worker
170*6777b538SAndroid Build Coastguard Worker xmlCleanupParser();
171*6777b538SAndroid Build Coastguard Worker
172*6777b538SAndroid Build Coastguard Worker return (status);
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker
175