1 #include "libxml.h" 2 #include <stdlib.h> 3 #include <stdio.h> 4 5 #if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED) 6 #include <libxml/globals.h> 7 #include <libxml/threads.h> 8 #include <libxml/parser.h> 9 #include <libxml/catalog.h> 10 #include <windows.h> 11 #include <string.h> 12 #include <assert.h> 13 14 #define MAX_ARGC 20 15 #define TEST_REPEAT_COUNT 500 16 17 static HANDLE tid[MAX_ARGC]; 18 19 static const char *catalog = "test/threads/complex.xml"; 20 static char *testfiles[] = { 21 "test/threads/abc.xml", 22 "test/threads/acb.xml", 23 "test/threads/bac.xml", 24 "test/threads/bca.xml", 25 "test/threads/cab.xml", 26 "test/threads/cba.xml", 27 "test/threads/invalid.xml", 28 }; 29 30 const char *Okay = "OK"; 31 const char *Failed = "Failed"; 32 33 #ifndef xmlDoValidityCheckingDefaultValue 34 #error xmlDoValidityCheckingDefaultValue is not a macro 35 #endif 36 #ifndef xmlGenericErrorContext 37 #error xmlGenericErrorContext is not a macro 38 #endif 39 40 static DWORD WINAPI 41 thread_specific_data(void *private_data) 42 { 43 xmlDocPtr myDoc; 44 const char *filename = (const char *) private_data; 45 int okay = 1; 46 47 if (!strcmp(filename, "test/threads/invalid.xml")) { 48 xmlDoValidityCheckingDefaultValue = 0; 49 xmlGenericErrorContext = stdout; 50 } else { 51 xmlDoValidityCheckingDefaultValue = 1; 52 xmlGenericErrorContext = stderr; 53 } 54 myDoc = xmlParseFile(filename); 55 if (myDoc) { 56 xmlFreeDoc(myDoc); 57 } else { 58 printf("parse failed\n"); 59 okay = 0; 60 } 61 if (!strcmp(filename, "test/threads/invalid.xml")) { 62 if (xmlDoValidityCheckingDefaultValue != 0) { 63 printf("ValidityCheckingDefaultValue override failed\n"); 64 okay = 0; 65 } 66 if (xmlGenericErrorContext != stdout) { 67 printf("xmlGenericErrorContext override failed\n"); 68 okay = 0; 69 } 70 } else { 71 if (xmlDoValidityCheckingDefaultValue != 1) { 72 printf("ValidityCheckingDefaultValue override failed\n"); 73 okay = 0; 74 } 75 if (xmlGenericErrorContext != stderr) { 76 printf("xmlGenericErrorContext override failed\n"); 77 okay = 0; 78 } 79 } 80 if (okay == 0) 81 return ((DWORD) Failed); 82 return ((DWORD) Okay); 83 } 84 85 int 86 main() 87 { 88 unsigned int i, repeat; 89 unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]); 90 DWORD results[MAX_ARGC]; 91 BOOL ret; 92 93 xmlInitParser(); 94 for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++) 95 { 96 xmlLoadCatalog(catalog); 97 98 for (i = 0; i < num_threads; i++) 99 { 100 results[i] = 0; 101 tid[i] = (HANDLE) -1; 102 } 103 104 for (i = 0; i < num_threads; i++) 105 { 106 DWORD useless; 107 tid[i] = CreateThread(NULL, 0, 108 thread_specific_data, testfiles[i], 0, &useless); 109 if (tid[i] == NULL) 110 { 111 perror("CreateThread"); 112 exit(1); 113 } 114 } 115 116 if (WaitForMultipleObjects (num_threads, tid, TRUE, INFINITE) == WAIT_FAILED) 117 perror ("WaitForMultipleObjects failed"); 118 119 for (i = 0; i < num_threads; i++) 120 { 121 ret = GetExitCodeThread (tid[i], &results[i]); 122 if (ret == 0) 123 { 124 perror("GetExitCodeThread"); 125 exit(1); 126 } 127 CloseHandle (tid[i]); 128 } 129 130 xmlCatalogCleanup(); 131 for (i = 0; i < num_threads; i++) { 132 if (results[i] != (DWORD) Okay) 133 printf("Thread %d handling %s failed\n", i, testfiles[i]); 134 } 135 } 136 137 xmlCleanupParser(); 138 xmlMemoryDump(); 139 140 return (0); 141 } 142 143 #else /* !LIBXML_THREADS_ENABLED */ 144 int 145 main() 146 { 147 fprintf(stderr, "libxml was not compiled with thread or catalog support\n"); 148 return (0); 149 } 150 #endif 151