1 #include "libxml.h"
2
3 #include <stdlib.h>
4 #include <stdio.h>
5
6 #if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
7 #include <libxml/globals.h>
8 #include <libxml/threads.h>
9 #include <libxml/parser.h>
10 #include <libxml/catalog.h>
11 #ifdef HAVE_PTHREAD_H
12 #include <pthread.h>
13 #elif defined HAVE_WIN32_THREADS
14 #include <windows.h>
15 #elif defined HAVE_BEOS_THREADS
16 #include <OS.h>
17 #endif
18 #include <string.h>
19 #if !defined(_MSC_VER)
20 #include <unistd.h>
21 #endif
22 #include <assert.h>
23
24 #define MAX_ARGC 20
25 #define TEST_REPEAT_COUNT 500
26 #ifdef HAVE_PTHREAD_H
27 static pthread_t tid[MAX_ARGC];
28 #elif defined HAVE_WIN32_THREADS
29 static HANDLE tid[MAX_ARGC];
30 #elif defined HAVE_BEOS_THREADS
31 static thread_id tid[MAX_ARGC];
32 #endif
33
34 typedef struct {
35 const char *filename;
36 int okay;
37 } xmlThreadParams;
38
39 static const char *catalog = "test/threads/complex.xml";
40 static xmlThreadParams threadParams[] = {
41 { "test/threads/abc.xml", 0 },
42 { "test/threads/acb.xml", 0 },
43 { "test/threads/bac.xml", 0 },
44 { "test/threads/bca.xml", 0 },
45 { "test/threads/cab.xml", 0 },
46 { "test/threads/cba.xml", 0 },
47 { "test/threads/invalid.xml", 0 }
48 };
49 static const unsigned int num_threads = sizeof(threadParams) /
50 sizeof(threadParams[0]);
51
52 #ifndef xmlDoValidityCheckingDefaultValue
53 #error xmlDoValidityCheckingDefaultValue is not a macro
54 #endif
55 #ifndef xmlGenericErrorContext
56 #error xmlGenericErrorContext is not a macro
57 #endif
58
59 static void *
thread_specific_data(void * private_data)60 thread_specific_data(void *private_data)
61 {
62 xmlDocPtr myDoc;
63 xmlThreadParams *params = (xmlThreadParams *) private_data;
64 const char *filename = params->filename;
65 int okay = 1;
66
67 if (!strcmp(filename, "test/threads/invalid.xml")) {
68 xmlDoValidityCheckingDefaultValue = 0;
69 xmlGenericErrorContext = stdout;
70 } else {
71 xmlDoValidityCheckingDefaultValue = 1;
72 xmlGenericErrorContext = stderr;
73 }
74 #ifdef LIBXML_SAX1_ENABLED
75 myDoc = xmlParseFile(filename);
76 #else
77 myDoc = xmlReadFile(filename, NULL, XML_WITH_CATALOG);
78 #endif
79 if (myDoc) {
80 xmlFreeDoc(myDoc);
81 } else {
82 printf("parse failed\n");
83 okay = 0;
84 }
85 if (!strcmp(filename, "test/threads/invalid.xml")) {
86 if (xmlDoValidityCheckingDefaultValue != 0) {
87 printf("ValidityCheckingDefaultValue override failed\n");
88 okay = 0;
89 }
90 if (xmlGenericErrorContext != stdout) {
91 printf("xmlGenericErrorContext override failed\n");
92 okay = 0;
93 }
94 } else {
95 if (xmlDoValidityCheckingDefaultValue != 1) {
96 printf("ValidityCheckingDefaultValue override failed\n");
97 okay = 0;
98 }
99 if (xmlGenericErrorContext != stderr) {
100 printf("xmlGenericErrorContext override failed\n");
101 okay = 0;
102 }
103 }
104 params->okay = okay;
105 return(NULL);
106 }
107
108 #ifdef HAVE_PTHREAD_H
109 int
main(void)110 main(void)
111 {
112 unsigned int i, repeat;
113 int ret;
114
115 xmlInitParser();
116 for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++) {
117 xmlLoadCatalog(catalog);
118
119 memset(tid, 0xff, sizeof(*tid)*num_threads);
120
121 for (i = 0; i < num_threads; i++) {
122 ret = pthread_create(&tid[i], NULL, thread_specific_data,
123 (void *) &threadParams[i]);
124 if (ret != 0) {
125 perror("pthread_create");
126 exit(1);
127 }
128 }
129 for (i = 0; i < num_threads; i++) {
130 void *result;
131 ret = pthread_join(tid[i], &result);
132 if (ret != 0) {
133 perror("pthread_join");
134 exit(1);
135 }
136 }
137
138 xmlCatalogCleanup();
139 for (i = 0; i < num_threads; i++)
140 if (threadParams[i].okay == 0)
141 printf("Thread %d handling %s failed\n", i,
142 threadParams[i].filename);
143 }
144 xmlCleanupParser();
145 xmlMemoryDump();
146 return (0);
147 }
148 #elif defined HAVE_WIN32_THREADS
149 static DWORD WINAPI
win32_thread_specific_data(void * private_data)150 win32_thread_specific_data(void *private_data)
151 {
152 thread_specific_data(private_data);
153 return(0);
154 }
155
156 int
main(void)157 main(void)
158 {
159 unsigned int i, repeat;
160 BOOL ret;
161
162 xmlInitParser();
163 for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++)
164 {
165 xmlLoadCatalog(catalog);
166
167 for (i = 0; i < num_threads; i++)
168 {
169 tid[i] = (HANDLE) -1;
170 }
171
172 for (i = 0; i < num_threads; i++)
173 {
174 DWORD useless;
175 tid[i] = CreateThread(NULL, 0,
176 win32_thread_specific_data, &threadParams[i], 0, &useless);
177 if (tid[i] == NULL)
178 {
179 perror("CreateThread");
180 exit(1);
181 }
182 }
183
184 if (WaitForMultipleObjects (num_threads, tid, TRUE, INFINITE) == WAIT_FAILED)
185 perror ("WaitForMultipleObjects failed");
186
187 for (i = 0; i < num_threads; i++)
188 {
189 DWORD exitCode;
190 ret = GetExitCodeThread (tid[i], &exitCode);
191 if (ret == 0)
192 {
193 perror("GetExitCodeThread");
194 exit(1);
195 }
196 CloseHandle (tid[i]);
197 }
198
199 xmlCatalogCleanup();
200 for (i = 0; i < num_threads; i++) {
201 if (threadParams[i].okay == 0)
202 printf("Thread %d handling %s failed\n", i,
203 threadParams[i].filename);
204 }
205 }
206
207 xmlCleanupParser();
208 xmlMemoryDump();
209
210 return (0);
211 }
212 #elif defined HAVE_BEOS_THREADS
213 int
main(void)214 main(void)
215 {
216 unsigned int i, repeat;
217 status_t ret;
218
219 xmlInitParser();
220 printf("Parser initialized\n");
221 for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++) {
222 printf("repeat: %d\n",repeat);
223 xmlLoadCatalog(catalog);
224 printf("loaded catalog: %s\n", catalog);
225 for (i = 0; i < num_threads; i++) {
226 tid[i] = (thread_id) -1;
227 }
228 printf("cleaned threads\n");
229 for (i = 0; i < num_threads; i++) {
230 tid[i] = spawn_thread(thread_specific_data, "xmlTestThread", B_NORMAL_PRIORITY, (void *) &threadParams[i]);
231 if (tid[i] < B_OK) {
232 perror("beos_thread_create");
233 exit(1);
234 }
235 printf("beos_thread_create %d -> %d\n", i, tid[i]);
236 }
237 for (i = 0; i < num_threads; i++) {
238 void *result;
239 ret = wait_for_thread(tid[i], &result);
240 printf("beos_thread_wait %d -> %d\n", i, ret);
241 if (ret != B_OK) {
242 perror("beos_thread_wait");
243 exit(1);
244 }
245 }
246
247 xmlCatalogCleanup();
248 ret = B_OK;
249 for (i = 0; i < num_threads; i++)
250 if (threadParams[i].okay == 0) {
251 printf("Thread %d handling %s failed\n", i,
252 threadParams[i].filename);
253 ret = B_ERROR;
254 }
255 }
256 xmlCleanupParser();
257 xmlMemoryDump();
258
259 if (ret == B_OK)
260 printf("testThread : BeOS : SUCCESS!\n");
261 else
262 printf("testThread : BeOS : FAILED!\n");
263
264 return (0);
265 }
266 #endif /* pthreads or BeOS threads */
267
268 #else /* !LIBXML_THREADS_ENABLED */
269 int
main(void)270 main(void)
271 {
272 fprintf(stderr, "libxml was not compiled with thread or catalog support\n");
273 return (0);
274 }
275 #endif
276