(root)/
libxml2-2.12.3/
testThreads.c
       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 *
      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
      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
      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