• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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