1 #include "libxml.h"
   2 
   3 #include <stdlib.h>
   4 #include <stdio.h>
   5 
   6 #if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_SAX1_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_BEOS_THREADS
  14 #include <OS.h>
  15 #endif
  16 #include <string.h>
  17 #if !defined(_MSC_VER)
  18 #include <unistd.h>
  19 #endif
  20 #include <assert.h>
  21 
  22 #define MAX_ARGC    20
  23 #ifdef HAVE_PTHREAD_H
  24 static pthread_t tid[MAX_ARGC];
  25 #elif defined HAVE_BEOS_THREADS
  26 static thread_id tid[MAX_ARGC];
  27 #endif
  28 
  29 static const char *catalog = "test/threads/complex.xml";
  30 static const char *testfiles[] = {
  31     "test/threads/abc.xml",
  32     "test/threads/acb.xml",
  33     "test/threads/bac.xml",
  34     "test/threads/bca.xml",
  35     "test/threads/cab.xml",
  36     "test/threads/cba.xml",
  37     "test/threads/invalid.xml",
  38 };
  39 
  40 static const char *Okay = "OK";
  41 static const char *Failed = "Failed";
  42 
  43 #ifndef xmlDoValidityCheckingDefaultValue
  44 #error xmlDoValidityCheckingDefaultValue is not a macro
  45 #endif
  46 #ifndef xmlGenericErrorContext
  47 #error xmlGenericErrorContext is not a macro
  48 #endif
  49 
  50 static void *
  51 thread_specific_data(void *private_data)
  52 {
  53     xmlDocPtr myDoc;
  54     const char *filename = (const char *) private_data;
  55     int okay = 1;
  56 
  57     if (!strcmp(filename, "test/threads/invalid.xml")) {
  58         xmlDoValidityCheckingDefaultValue = 0;
  59         xmlGenericErrorContext = stdout;
  60     } else {
  61         xmlDoValidityCheckingDefaultValue = 1;
  62         xmlGenericErrorContext = stderr;
  63     }
  64     myDoc = xmlParseFile(filename);
  65     if (myDoc) {
  66         xmlFreeDoc(myDoc);
  67     } else {
  68         printf("parse failed\n");
  69     okay = 0;
  70     }
  71     if (!strcmp(filename, "test/threads/invalid.xml")) {
  72         if (xmlDoValidityCheckingDefaultValue != 0) {
  73         printf("ValidityCheckingDefaultValue override failed\n");
  74         okay = 0;
  75     }
  76         if (xmlGenericErrorContext != stdout) {
  77         printf("xmlGenericErrorContext override failed\n");
  78         okay = 0;
  79     }
  80     } else {
  81         if (xmlDoValidityCheckingDefaultValue != 1) {
  82         printf("ValidityCheckingDefaultValue override failed\n");
  83         okay = 0;
  84     }
  85         if (xmlGenericErrorContext != stderr) {
  86         printf("xmlGenericErrorContext override failed\n");
  87         okay = 0;
  88     }
  89     }
  90     if (okay == 0)
  91     return((void *) Failed);
  92     return ((void *) Okay);
  93 }
  94 
  95 #ifdef HAVE_PTHREAD_H
  96 int
  97 main(void)
  98 {
  99     unsigned int i, repeat;
 100     unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
 101     void *results[MAX_ARGC];
 102     int ret;
 103 
 104     xmlInitParser();
 105     for (repeat = 0;repeat < 500;repeat++) {
 106     xmlLoadCatalog(catalog);
 107 
 108     for (i = 0; i < num_threads; i++) {
 109         results[i] = NULL;
 110         tid[i] = (pthread_t) -1;
 111     }
 112 
 113     for (i = 0; i < num_threads; i++) {
 114         ret = pthread_create(&tid[i], NULL, thread_specific_data,
 115                  (void *) testfiles[i]);
 116         if (ret != 0) {
 117         perror("pthread_create");
 118         exit(1);
 119         }
 120     }
 121     for (i = 0; i < num_threads; i++) {
 122         ret = pthread_join(tid[i], &results[i]);
 123         if (ret != 0) {
 124         perror("pthread_join");
 125         exit(1);
 126         }
 127     }
 128 
 129     xmlCatalogCleanup();
 130     for (i = 0; i < num_threads; i++)
 131         if (results[i] != (void *) Okay)
 132         printf("Thread %d handling %s failed\n", i, testfiles[i]);
 133     }
 134     xmlCleanupParser();
 135     xmlMemoryDump();
 136     return (0);
 137 }
 138 #elif defined HAVE_BEOS_THREADS
 139 int
 140 main(void)
 141 {
 142     unsigned int i, repeat;
 143     unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
 144     void *results[MAX_ARGC];
 145     status_t ret;
 146 
 147     xmlInitParser();
 148     printf("Parser initialized\n");
 149     for (repeat = 0;repeat < 500;repeat++) {
 150     printf("repeat: %d\n",repeat);
 151     xmlLoadCatalog(catalog);
 152     printf("loaded catalog: %s\n", catalog);
 153     for (i = 0; i < num_threads; i++) {
 154         results[i] = NULL;
 155         tid[i] = (thread_id) -1;
 156     }
 157     printf("cleaned threads\n");
 158     for (i = 0; i < num_threads; i++) {
 159         tid[i] = spawn_thread(thread_specific_data, "xmlTestThread", B_NORMAL_PRIORITY, (void *) testfiles[i]);
 160         if (tid[i] < B_OK) {
 161             perror("beos_thread_create");
 162             exit(1);
 163         }
 164         printf("beos_thread_create %d -> %d\n", i, tid[i]);
 165     }
 166     for (i = 0; i < num_threads; i++) {
 167         ret = wait_for_thread(tid[i], &results[i]);
 168         printf("beos_thread_wait %d -> %d\n", i, ret);
 169         if (ret != B_OK) {
 170             perror("beos_thread_wait");
 171             exit(1);
 172         }
 173     }
 174 
 175     xmlCatalogCleanup();
 176     ret = B_OK;
 177     for (i = 0; i < num_threads; i++)
 178         if (results[i] != (void *) Okay) {
 179             printf("Thread %d handling %s failed\n", i, testfiles[i]);
 180             ret = B_ERROR;
 181         }
 182     }
 183     xmlCleanupParser();
 184     xmlMemoryDump();
 185 
 186     if (ret == B_OK)
 187         printf("testThread : BeOS : SUCCESS!\n");
 188     else
 189         printf("testThread : BeOS : FAILED!\n");
 190 
 191     return (0);
 192 }
 193 #endif /* pthreads or BeOS threads */
 194 
 195 #else /* !LIBXML_THREADS_ENABLED */
 196 int
 197 main(void)
 198 {
 199     fprintf(stderr, "libxml was not compiled with thread or catalog support\n");
 200     return (0);
 201 }
 202 #endif