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