1c1099be5eb3e78ae6cef1b2c39b21e7b36a59035William M. Brack#include "libxml.h"
2c1099be5eb3e78ae6cef1b2c39b21e7b36a59035William M. Brack
3ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#include <stdlib.h>
43c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#include <stdio.h>
5ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard
6d0cf7f6eea7331cc398c232d7879e4239d989e14Daniel Veillard#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_SAX1_ENABLED)
7ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#include <libxml/globals.h>
8ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#include <libxml/threads.h>
9ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#include <libxml/parser.h>
10ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#include <libxml/catalog.h>
1182cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard#ifdef HAVE_PTHREAD_H
12ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#include <pthread.h>
1382cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard#elif defined HAVE_BEOS_THREADS
1482cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard#include <OS.h>
1582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard#endif
16ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#include <string.h>
17082ff5039f3291aa82b6480e4fc2725c082df8ebIgor Zlatkovic#if !defined(_MSC_VER)
18ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#include <unistd.h>
19082ff5039f3291aa82b6480e4fc2725c082df8ebIgor Zlatkovic#endif
20ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#include <assert.h>
21ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard
22ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#define	MAX_ARGC	20
2382cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard#ifdef HAVE_PTHREAD_H
24ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillardstatic pthread_t tid[MAX_ARGC];
2582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard#elif defined HAVE_BEOS_THREADS
2682cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillardstatic thread_id tid[MAX_ARGC];
2782cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard#endif
28ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard
29ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillardstatic const char *catalog = "test/threads/complex.xml";
30ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillardstatic const char *testfiles[] = {
31ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    "test/threads/abc.xml",
32ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    "test/threads/acb.xml",
33ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    "test/threads/bac.xml",
34ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    "test/threads/bca.xml",
35ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    "test/threads/cab.xml",
36ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    "test/threads/cba.xml",
37ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    "test/threads/invalid.xml",
38ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard};
39ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard
4024505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillardstatic const char *Okay = "OK";
4124505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillardstatic const char *Failed = "Failed";
423c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard
433c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#ifndef xmlDoValidityCheckingDefaultValue
443c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#error xmlDoValidityCheckingDefaultValue is not a macro
453c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#endif
463c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#ifndef xmlGenericErrorContext
473c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#error xmlGenericErrorContext is not a macro
483c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#endif
493c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard
50ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillardstatic void *
51ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillardthread_specific_data(void *private_data)
52ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard{
53ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    xmlDocPtr myDoc;
54ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    const char *filename = (const char *) private_data;
553c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    int okay = 1;
56ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard
573c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    if (!strcmp(filename, "test/threads/invalid.xml")) {
58ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard        xmlDoValidityCheckingDefaultValue = 0;
59ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard        xmlGenericErrorContext = stdout;
60ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    } else {
61ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard        xmlDoValidityCheckingDefaultValue = 1;
62ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard        xmlGenericErrorContext = stderr;
63ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    }
64ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    myDoc = xmlParseFile(filename);
65ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    if (myDoc) {
66ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard        xmlFreeDoc(myDoc);
673c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    } else {
68ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard        printf("parse failed\n");
693c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	okay = 0;
703c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    }
713c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    if (!strcmp(filename, "test/threads/invalid.xml")) {
723c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard        if (xmlDoValidityCheckingDefaultValue != 0) {
73ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard	    printf("ValidityCheckingDefaultValue override failed\n");
743c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    okay = 0;
753c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	}
763c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard        if (xmlGenericErrorContext != stdout) {
773c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    printf("xmlGenericErrorContext override failed\n");
783c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    okay = 0;
793c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	}
80ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    } else {
813c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard        if (xmlDoValidityCheckingDefaultValue != 1) {
82ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard	    printf("ValidityCheckingDefaultValue override failed\n");
833c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    okay = 0;
843c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	}
853c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard        if (xmlGenericErrorContext != stderr) {
863c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    printf("xmlGenericErrorContext override failed\n");
873c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    okay = 0;
883c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	}
89ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    }
903c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    if (okay == 0)
913c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	return((void *) Failed);
923c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    return ((void *) Okay);
93ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard}
94ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard
9582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard#ifdef HAVE_PTHREAD_H
96ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillardint
97a71a8ef127c8811db2ebbce8086d6e2a8f3d241eWilliam M. Brackmain(void)
98ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard{
993c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    unsigned int i, repeat;
100ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
1013c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    void *results[MAX_ARGC];
1023c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    int ret;
103ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard
104ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    xmlInitParser();
10589cad536e3e38002bfc931acfa2e0645d4b08a51Daniel Veillard    for (repeat = 0;repeat < 500;repeat++) {
1063c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	xmlLoadCatalog(catalog);
107ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard
108d794a84a9e147498069b4c582d57b899bf068187Andrew W. Nosenko        memset(results, 0, sizeof(*results)*num_threads);
109d794a84a9e147498069b4c582d57b899bf068187Andrew W. Nosenko        memset(tid, 0xff, sizeof(*tid)*num_threads);
110ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard
1113c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	for (i = 0; i < num_threads; i++) {
11224505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    ret = pthread_create(&tid[i], NULL, thread_specific_data,
1133c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard				 (void *) testfiles[i]);
1143c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    if (ret != 0) {
1153c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard		perror("pthread_create");
1163c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard		exit(1);
1173c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    }
1183c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	}
1193c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	for (i = 0; i < num_threads; i++) {
1203c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    ret = pthread_join(tid[i], &results[i]);
1213c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    if (ret != 0) {
1223c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard		perror("pthread_join");
1233c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard		exit(1);
1243c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    }
1253c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	}
1263c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard
1273c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	xmlCatalogCleanup();
1283c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	for (i = 0; i < num_threads; i++)
1293c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard	    if (results[i] != (void *) Okay)
1303c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard		printf("Thread %d handling %s failed\n", i, testfiles[i]);
1313c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard    }
132ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    xmlCleanupParser();
133ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    xmlMemoryDump();
134ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    return (0);
135ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard}
13682cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard#elif defined HAVE_BEOS_THREADS
13782cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillardint
13882cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillardmain(void)
13982cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard{
14082cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    unsigned int i, repeat;
14182cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
14282cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    void *results[MAX_ARGC];
14382cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    status_t ret;
14482cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard
14582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    xmlInitParser();
14682cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    printf("Parser initialized\n");
14782cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    for (repeat = 0;repeat < 500;repeat++) {
14882cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    printf("repeat: %d\n",repeat);
14982cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	xmlLoadCatalog(catalog);
15082cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	printf("loaded catalog: %s\n", catalog);
15182cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	for (i = 0; i < num_threads; i++) {
15282cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	    results[i] = NULL;
15382cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	    tid[i] = (thread_id) -1;
15482cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	}
15582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	printf("cleaned threads\n");
15682cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	for (i = 0; i < num_threads; i++) {
15782cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard		tid[i] = spawn_thread(thread_specific_data, "xmlTestThread", B_NORMAL_PRIORITY, (void *) testfiles[i]);
15882cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard		if (tid[i] < B_OK) {
15982cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard			perror("beos_thread_create");
16082cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard			exit(1);
16182cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard		}
16282cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard		printf("beos_thread_create %d -> %d\n", i, tid[i]);
16382cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	}
16482cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	for (i = 0; i < num_threads; i++) {
16582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	    ret = wait_for_thread(tid[i], &results[i]);
16682cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	    printf("beos_thread_wait %d -> %d\n", i, ret);
16782cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	    if (ret != B_OK) {
16882cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard			perror("beos_thread_wait");
16982cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard			exit(1);
17082cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	    }
17182cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	}
17282cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard
17382cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	xmlCatalogCleanup();
17482cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	ret = B_OK;
17582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	for (i = 0; i < num_threads; i++)
17682cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	    if (results[i] != (void *) Okay) {
17782cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard			printf("Thread %d handling %s failed\n", i, testfiles[i]);
17882cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard			ret = B_ERROR;
17982cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard		}
18082cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    }
18182cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    xmlCleanupParser();
18282cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    xmlMemoryDump();
18382cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard
18482cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	if (ret == B_OK)
18582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard		printf("testThread : BeOS : SUCCESS!\n");
18682cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard	else
18782cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard		printf("testThread : BeOS : FAILED!\n");
18882cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard
18982cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard    return (0);
19082cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard}
19182cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard#endif /* pthreads or BeOS threads */
192ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard
193ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#else /* !LIBXML_THREADS_ENABLED */
194ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillardint
195118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardmain(void)
196ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard{
197a4617b8aba43d2ce8e033cb04de599b4273cb94bDaniel Veillard    fprintf(stderr, "libxml was not compiled with thread or catalog support\n");
198ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard    return (0);
199ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard}
200ab7488efa556f86d18c253b80e7b3591e255546aDaniel Veillard#endif
201