Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / libxslt / xsltproc / testThreads.c
blob05f0039c350be058d856bf83a53c8d27db97b040
1 /**
2 * testThreads.c: testing of heavilly multithreaded concurrent accesses
4 * See Copyright for the status of this software.
6 * daniel@veillard.com
7 */
9 /*
10 * TODO: extend it to allow giving the stylesheets/input as filenames on the
11 * command line to test specifics, also add exslt
14 #include "config.h"
15 #include "libexslt/exslt.h"
16 #include <stdlib.h>
17 #include <stdio.h>
19 #define _REENTRANT
20 #include <libxml/xmlversion.h>
22 #if defined(LIBXML_THREAD_ENABLED) && defined(HAVE_PTHREAD_H)
24 #include <libxml/globals.h>
25 #include <libxml/threads.h>
26 #include <libxml/parser.h>
27 #include <libxml/catalog.h>
28 #include <libxml/xpathInternals.h>
29 #include <libxslt/xslt.h>
30 #include <libxslt/xsltInternals.h>
31 #include <libxslt/transform.h>
32 #include <libxslt/xsltutils.h>
33 #include <libxslt/extensions.h>
34 #include <libexslt/exsltconfig.h>
35 #include <pthread.h>
36 #include <string.h>
37 #if !defined(_MSC_VER)
38 #include <unistd.h>
39 #endif
40 #include <assert.h>
42 #define MAX_ARGC 20
44 static pthread_t tid[MAX_ARGC];
46 #define EXT_NS BAD_CAST "http://foo.org"
47 #define EXT_DATA "bar"
49 const char *stylesheet = "<xsl:stylesheet version='1.0' \
50 xmlns:xsl='http://www.w3.org/1999/XSL/Transform' \
51 xmlns:foo='http://foo.org' \
52 extension-element-prefixes='foo'>\
53 <xsl:template match='text()'>\
54 Success <xsl:value-of select='foo:foo()'/>\
55 </xsl:template>\
56 </xsl:stylesheet>\
59 int init = 0;
61 const char *doc = "<doc>Failed</doc>";
62 const char *expect = "<?xml version=\"1.0\"?>\nSuccess foo\n";
64 static void fooFunction(xmlXPathParserContextPtr ctxt,
65 int nargs ATTRIBUTE_UNUSED) {
66 xmlXPathReturnString(ctxt, xmlStrdup(BAD_CAST "foo"));
69 static
70 void * registerFooExtensions(ATTRIBUTE_UNUSED xsltTransformContextPtr ctxt,
71 ATTRIBUTE_UNUSED const xmlChar *URI) {
72 xsltRegisterExtModuleFunction(BAD_CAST "foo", EXT_NS, fooFunction);
73 return((void *)EXT_DATA);
76 static
77 void shutdownFooExtensions(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
78 const xmlChar *URI, void *data) {
79 const char *str = (const char *) data;
80 if (!xmlStrEqual(URI, EXT_NS)) {
81 fprintf(stderr, "Mismatch in extensions shutdown URI");
83 if (!xmlStrEqual(BAD_CAST str, BAD_CAST EXT_DATA)) {
84 fprintf(stderr, "Mismatch in extensions shutdown DATA");
88 static void registerFooModule(void) {
89 xsltRegisterExtModule(EXT_NS, registerFooExtensions, shutdownFooExtensions);
92 static void *
93 threadRoutine1(void *data)
95 xmlDocPtr input;
96 xmlDocPtr style;
97 xmlDocPtr res;
98 xmlChar *result;
99 int len;
100 xsltStylesheetPtr cur;
101 int id = (int)(unsigned long) data;
103 input = xmlReadMemory(doc, strlen(doc), "doc.xml", NULL, 0);
104 if (input == NULL) {
105 fprintf(stderr, "Thread id %d failed to parse input\n", id);
106 exit(1);
108 style = xmlReadMemory(stylesheet, strlen(stylesheet), "doc.xsl", NULL, 0);
109 if (style == NULL) {
110 fprintf(stderr, "Thread id %d failed to parse stylesheet\n", id);
111 exit(1);
113 cur = xsltParseStylesheetDoc(style);
114 if (cur == NULL) {
115 fprintf(stderr, "Thread id %d failed to compile stylesheet\n", id);
116 exit(1);
118 res = xsltApplyStylesheet(cur, input, NULL);
119 if (res == NULL) {
120 fprintf(stderr, "Thread id %d failed to apply stylesheet\n", id);
121 exit(1);
123 if (xsltSaveResultToString(&result, &len, res, cur) < 0) {
124 fprintf(stderr, "Thread id %d failed to output result\n", id);
125 exit(1);
127 if (!xmlStrEqual(BAD_CAST expect, result)) {
128 fprintf(stderr, "Thread id %d output not conform\n", id);
129 exit(1);
131 xsltFreeStylesheet(cur);
132 xmlFreeDoc(input);
133 xmlFreeDoc(res);
134 xmlFree(result);
135 return(0);
138 static void *
139 threadRoutine2(void *data)
141 xmlDocPtr input;
142 xmlDocPtr res;
143 xmlChar *result;
144 int len;
145 xsltStylesheetPtr cur = (xsltStylesheetPtr) data;
147 if (cur == NULL) {
148 fprintf(stderr, "Thread failed to get the stylesheet\n");
149 exit(1);
151 input = xmlReadMemory(doc, strlen(doc), "doc.xml", NULL, 0);
152 if (input == NULL) {
153 fprintf(stderr, "Thread failed to parse input\n");
154 exit(1);
156 res = xsltApplyStylesheet(cur, input, NULL);
157 if (res == NULL) {
158 fprintf(stderr, "Thread failed to apply stylesheet\n");
159 exit(1);
161 if (xsltSaveResultToString(&result, &len, res, cur) < 0) {
162 fprintf(stderr, "Thread failed to output result\n");
163 exit(1);
165 if (!xmlStrEqual(BAD_CAST expect, result)) {
166 fprintf(stderr, "Thread output not conform\n");
167 exit(1);
169 xmlFreeDoc(input);
170 xmlFreeDoc(res);
171 xmlFree(result);
172 return(0);
175 main(void)
177 unsigned int i, repeat;
178 unsigned int num_threads = 8;
179 void *results[MAX_ARGC];
180 int ret;
182 xmlInitParser();
185 * Register the EXSLT extensions and the test module
187 exsltRegisterAll();
188 xsltRegisterTestModule();
191 * Register our own extension module
193 registerFooModule();
196 * First pass each thread has its own version of the stylesheet
197 * each of them will initialize and shutdown the extension
199 printf("Pass 1\n");
200 for (repeat = 0;repeat < 500;repeat++) {
201 memset(results, 0, sizeof(*results)*num_threads);
202 memset(tid, 0xff, sizeof(*tid)*num_threads);
204 for (i = 0; i < num_threads; i++) {
205 ret = pthread_create(&tid[i], NULL, threadRoutine1,
206 (void *) (unsigned long) i);
207 if (ret != 0) {
208 perror("pthread_create");
209 exit(1);
212 for (i = 0; i < num_threads; i++) {
213 ret = pthread_join(tid[i], &results[i]);
214 if (ret != 0) {
215 perror("pthread_join");
216 exit(1);
222 * Second pass all threads share the same stylesheet instance
223 * look for transformation clashes
225 printf("Pass 2\n");
226 for (repeat = 0;repeat < 500;repeat++) {
227 xmlDocPtr style;
228 xsltStylesheetPtr cur;
230 style = xmlReadMemory(stylesheet, strlen(stylesheet), "doc.xsl",
231 NULL, 0);
232 if (style == NULL) {
233 fprintf(stderr, "Main failed to parse stylesheet\n");
234 exit(1);
236 cur = xsltParseStylesheetDoc(style);
237 if (cur == NULL) {
238 fprintf(stderr, "Main failed to compile stylesheet\n");
239 exit(1);
241 memset(results, 0, sizeof(*results)*num_threads);
242 memset(tid, 0xff, sizeof(*tid)*num_threads);
244 for (i = 0; i < num_threads; i++) {
245 ret = pthread_create(&tid[i], NULL, threadRoutine2, (void *) cur);
246 if (ret != 0) {
247 perror("pthread_create");
248 exit(1);
251 for (i = 0; i < num_threads; i++) {
252 ret = pthread_join(tid[i], &results[i]);
253 if (ret != 0) {
254 perror("pthread_join");
255 exit(1);
258 xsltFreeStylesheet(cur);
260 xsltCleanupGlobals();
261 xmlCleanupParser();
262 xmlMemoryDump();
263 printf("Ok\n");
264 return (0);
266 #else /* !LIBXML_THREADS_ENABLED | !HAVE_PTHREAD_H */
268 main(void)
270 fprintf(stderr, "libxml was not compiled with thread\n");
271 return (0);
273 #endif