@helm2/poc_jenki_rce 0.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of @helm2/poc_jenki_rce might be problematic. Click here for more details.

Files changed (160) hide show
  1. package/LICENSE +19 -0
  2. package/Makefile +18 -0
  3. package/README.md +52 -0
  4. package/binding.gyp +81 -0
  5. package/index.d.ts +273 -0
  6. package/index.js +45 -0
  7. package/lib/bindings.js +1 -0
  8. package/lib/document.js +118 -0
  9. package/lib/element.js +82 -0
  10. package/lib/sax_parser.js +38 -0
  11. package/package.json +70 -0
  12. package/src/html_document.cc +7 -0
  13. package/src/html_document.h +18 -0
  14. package/src/libxmljs.cc +252 -0
  15. package/src/libxmljs.h +53 -0
  16. package/src/xml_attribute.cc +173 -0
  17. package/src/xml_attribute.h +40 -0
  18. package/src/xml_comment.cc +117 -0
  19. package/src/xml_comment.h +30 -0
  20. package/src/xml_document.cc +810 -0
  21. package/src/xml_document.h +67 -0
  22. package/src/xml_element.cc +565 -0
  23. package/src/xml_element.h +61 -0
  24. package/src/xml_namespace.cc +158 -0
  25. package/src/xml_namespace.h +39 -0
  26. package/src/xml_node.cc +761 -0
  27. package/src/xml_node.h +73 -0
  28. package/src/xml_pi.cc +161 -0
  29. package/src/xml_pi.h +34 -0
  30. package/src/xml_sax_parser.cc +424 -0
  31. package/src/xml_sax_parser.h +73 -0
  32. package/src/xml_syntax_error.cc +66 -0
  33. package/src/xml_syntax_error.h +25 -0
  34. package/src/xml_text.cc +320 -0
  35. package/src/xml_text.h +48 -0
  36. package/src/xml_textwriter.cc +315 -0
  37. package/src/xml_textwriter.h +62 -0
  38. package/src/xml_xpath_context.cc +70 -0
  39. package/src/xml_xpath_context.h +23 -0
  40. package/vendor/libxml/Copyright +23 -0
  41. package/vendor/libxml/DOCBparser.c +305 -0
  42. package/vendor/libxml/HTMLparser.c +7287 -0
  43. package/vendor/libxml/HTMLtree.c +1200 -0
  44. package/vendor/libxml/Makefile +2983 -0
  45. package/vendor/libxml/SAX.c +180 -0
  46. package/vendor/libxml/SAX2.c +3036 -0
  47. package/vendor/libxml/buf.c +1351 -0
  48. package/vendor/libxml/buf.h +72 -0
  49. package/vendor/libxml/c14n.c +2234 -0
  50. package/vendor/libxml/catalog.c +3828 -0
  51. package/vendor/libxml/chvalid.c +336 -0
  52. package/vendor/libxml/config.h +294 -0
  53. package/vendor/libxml/config.h.gch +0 -0
  54. package/vendor/libxml/debugXML.c +3423 -0
  55. package/vendor/libxml/dict.c +1298 -0
  56. package/vendor/libxml/elfgcchack.h +17818 -0
  57. package/vendor/libxml/enc.h +32 -0
  58. package/vendor/libxml/encoding.c +3975 -0
  59. package/vendor/libxml/entities.c +1163 -0
  60. package/vendor/libxml/error.c +998 -0
  61. package/vendor/libxml/globals.c +1126 -0
  62. package/vendor/libxml/hash.c +1146 -0
  63. package/vendor/libxml/include/libxml/DOCBparser.h +96 -0
  64. package/vendor/libxml/include/libxml/HTMLparser.h +306 -0
  65. package/vendor/libxml/include/libxml/HTMLtree.h +147 -0
  66. package/vendor/libxml/include/libxml/Makefile +725 -0
  67. package/vendor/libxml/include/libxml/Makefile.am +54 -0
  68. package/vendor/libxml/include/libxml/Makefile.in +725 -0
  69. package/vendor/libxml/include/libxml/SAX.h +173 -0
  70. package/vendor/libxml/include/libxml/SAX2.h +178 -0
  71. package/vendor/libxml/include/libxml/c14n.h +128 -0
  72. package/vendor/libxml/include/libxml/catalog.h +182 -0
  73. package/vendor/libxml/include/libxml/chvalid.h +230 -0
  74. package/vendor/libxml/include/libxml/debugXML.h +217 -0
  75. package/vendor/libxml/include/libxml/dict.h +79 -0
  76. package/vendor/libxml/include/libxml/encoding.h +245 -0
  77. package/vendor/libxml/include/libxml/entities.h +151 -0
  78. package/vendor/libxml/include/libxml/globals.h +508 -0
  79. package/vendor/libxml/include/libxml/hash.h +236 -0
  80. package/vendor/libxml/include/libxml/list.h +137 -0
  81. package/vendor/libxml/include/libxml/nanoftp.h +163 -0
  82. package/vendor/libxml/include/libxml/nanohttp.h +81 -0
  83. package/vendor/libxml/include/libxml/parser.h +1243 -0
  84. package/vendor/libxml/include/libxml/parserInternals.h +644 -0
  85. package/vendor/libxml/include/libxml/pattern.h +100 -0
  86. package/vendor/libxml/include/libxml/relaxng.h +217 -0
  87. package/vendor/libxml/include/libxml/schemasInternals.h +958 -0
  88. package/vendor/libxml/include/libxml/schematron.h +142 -0
  89. package/vendor/libxml/include/libxml/threads.h +89 -0
  90. package/vendor/libxml/include/libxml/tree.h +1311 -0
  91. package/vendor/libxml/include/libxml/uri.h +94 -0
  92. package/vendor/libxml/include/libxml/valid.h +458 -0
  93. package/vendor/libxml/include/libxml/xinclude.h +129 -0
  94. package/vendor/libxml/include/libxml/xlink.h +189 -0
  95. package/vendor/libxml/include/libxml/xmlIO.h +368 -0
  96. package/vendor/libxml/include/libxml/xmlautomata.h +146 -0
  97. package/vendor/libxml/include/libxml/xmlerror.h +945 -0
  98. package/vendor/libxml/include/libxml/xmlexports.h +77 -0
  99. package/vendor/libxml/include/libxml/xmlmemory.h +224 -0
  100. package/vendor/libxml/include/libxml/xmlmodule.h +57 -0
  101. package/vendor/libxml/include/libxml/xmlreader.h +428 -0
  102. package/vendor/libxml/include/libxml/xmlregexp.h +222 -0
  103. package/vendor/libxml/include/libxml/xmlsave.h +88 -0
  104. package/vendor/libxml/include/libxml/xmlschemas.h +246 -0
  105. package/vendor/libxml/include/libxml/xmlschemastypes.h +151 -0
  106. package/vendor/libxml/include/libxml/xmlstring.h +140 -0
  107. package/vendor/libxml/include/libxml/xmlunicode.h +202 -0
  108. package/vendor/libxml/include/libxml/xmlversion.h +484 -0
  109. package/vendor/libxml/include/libxml/xmlwin32version.h +239 -0
  110. package/vendor/libxml/include/libxml/xmlwriter.h +488 -0
  111. package/vendor/libxml/include/libxml/xpath.h +564 -0
  112. package/vendor/libxml/include/libxml/xpathInternals.h +632 -0
  113. package/vendor/libxml/include/libxml/xpointer.h +114 -0
  114. package/vendor/libxml/include/win32config.h +122 -0
  115. package/vendor/libxml/include/wsockcompat.h +54 -0
  116. package/vendor/libxml/legacy.c +1343 -0
  117. package/vendor/libxml/libxml.h +134 -0
  118. package/vendor/libxml/list.c +779 -0
  119. package/vendor/libxml/nanoftp.c +2118 -0
  120. package/vendor/libxml/nanohttp.c +1899 -0
  121. package/vendor/libxml/parser.c +15553 -0
  122. package/vendor/libxml/parserInternals.c +2164 -0
  123. package/vendor/libxml/pattern.c +2621 -0
  124. package/vendor/libxml/relaxng.c +11101 -0
  125. package/vendor/libxml/rngparser.c +1595 -0
  126. package/vendor/libxml/runsuite.c +1157 -0
  127. package/vendor/libxml/save.h +36 -0
  128. package/vendor/libxml/schematron.c +1787 -0
  129. package/vendor/libxml/threads.c +1049 -0
  130. package/vendor/libxml/timsort.h +601 -0
  131. package/vendor/libxml/tree.c +10183 -0
  132. package/vendor/libxml/trio.c +6895 -0
  133. package/vendor/libxml/trio.h +230 -0
  134. package/vendor/libxml/triodef.h +228 -0
  135. package/vendor/libxml/trionan.c +914 -0
  136. package/vendor/libxml/trionan.h +84 -0
  137. package/vendor/libxml/triop.h +150 -0
  138. package/vendor/libxml/triostr.c +2112 -0
  139. package/vendor/libxml/triostr.h +144 -0
  140. package/vendor/libxml/uri.c +2561 -0
  141. package/vendor/libxml/valid.c +7138 -0
  142. package/vendor/libxml/xinclude.c +2657 -0
  143. package/vendor/libxml/xlink.c +183 -0
  144. package/vendor/libxml/xmlIO.c +4135 -0
  145. package/vendor/libxml/xmlcatalog.c +624 -0
  146. package/vendor/libxml/xmllint.c +3796 -0
  147. package/vendor/libxml/xmlmemory.c +1163 -0
  148. package/vendor/libxml/xmlmodule.c +468 -0
  149. package/vendor/libxml/xmlreader.c +6033 -0
  150. package/vendor/libxml/xmlregexp.c +8271 -0
  151. package/vendor/libxml/xmlsave.c +2735 -0
  152. package/vendor/libxml/xmlschemas.c +29173 -0
  153. package/vendor/libxml/xmlschemastypes.c +6276 -0
  154. package/vendor/libxml/xmlstring.c +1050 -0
  155. package/vendor/libxml/xmlunicode.c +3179 -0
  156. package/vendor/libxml/xmlwriter.c +4738 -0
  157. package/vendor/libxml/xpath.c +14734 -0
  158. package/vendor/libxml/xpointer.c +2969 -0
  159. package/vendor/libxml/xzlib.c +815 -0
  160. package/vendor/libxml/xzlib.h +19 -0
@@ -0,0 +1,1049 @@
1
+ /**
2
+ * threads.c: set of generic threading related routines
3
+ *
4
+ * See Copyright for the status of this software.
5
+ *
6
+ * Gary Pennington <Gary.Pennington@uk.sun.com>
7
+ * daniel@veillard.com
8
+ */
9
+
10
+ #define IN_LIBXML
11
+ #include "libxml.h"
12
+
13
+ #include <string.h>
14
+
15
+ #include <libxml/threads.h>
16
+ #include <libxml/globals.h>
17
+
18
+ #ifdef HAVE_SYS_TYPES_H
19
+ #include <sys/types.h>
20
+ #endif
21
+ #ifdef HAVE_UNISTD_H
22
+ #include <unistd.h>
23
+ #endif
24
+ #ifdef HAVE_STDLIB_H
25
+ #include <stdlib.h>
26
+ #endif
27
+ #ifdef HAVE_PTHREAD_H
28
+ #include <pthread.h>
29
+ #elif defined HAVE_WIN32_THREADS
30
+ #define WIN32_LEAN_AND_MEAN
31
+ #include <windows.h>
32
+ #ifndef HAVE_COMPILER_TLS
33
+ #include <process.h>
34
+ #endif
35
+ #endif
36
+
37
+ #ifdef HAVE_BEOS_THREADS
38
+ #include <OS.h>
39
+ #include <TLS.h>
40
+ #endif
41
+
42
+ #if defined(SOLARIS)
43
+ #include <note.h>
44
+ #endif
45
+
46
+ /* #define DEBUG_THREADS */
47
+
48
+ #ifdef HAVE_PTHREAD_H
49
+
50
+ #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 303) && \
51
+ defined(__GLIBC__) && defined(__linux__)
52
+
53
+ static int libxml_is_threaded = -1;
54
+
55
+ #define XML_PTHREAD_WEAK
56
+
57
+ #pragma weak pthread_once
58
+ #pragma weak pthread_getspecific
59
+ #pragma weak pthread_setspecific
60
+ #pragma weak pthread_key_create
61
+ #pragma weak pthread_key_delete
62
+ #pragma weak pthread_mutex_init
63
+ #pragma weak pthread_mutex_destroy
64
+ #pragma weak pthread_mutex_lock
65
+ #pragma weak pthread_mutex_unlock
66
+ #pragma weak pthread_cond_init
67
+ #pragma weak pthread_cond_destroy
68
+ #pragma weak pthread_cond_wait
69
+ #pragma weak pthread_equal
70
+ #pragma weak pthread_self
71
+ #pragma weak pthread_key_create
72
+ #pragma weak pthread_key_delete
73
+ #pragma weak pthread_cond_signal
74
+
75
+ #else /* __GNUC__, __GLIBC__, __linux__ */
76
+
77
+ static int libxml_is_threaded = 1;
78
+
79
+ #endif /* __GNUC__, __GLIBC__, __linux__ */
80
+
81
+ #endif /* HAVE_PTHREAD_H */
82
+
83
+ /*
84
+ * TODO: this module still uses malloc/free and not xmlMalloc/xmlFree
85
+ * to avoid some craziness since xmlMalloc/xmlFree may actually
86
+ * be hosted on allocated blocks needing them for the allocation ...
87
+ */
88
+
89
+ /*
90
+ * xmlMutex are a simple mutual exception locks
91
+ */
92
+ struct _xmlMutex {
93
+ #ifdef HAVE_PTHREAD_H
94
+ pthread_mutex_t lock;
95
+ #elif defined HAVE_WIN32_THREADS
96
+ HANDLE mutex;
97
+ #elif defined HAVE_BEOS_THREADS
98
+ sem_id sem;
99
+ thread_id tid;
100
+ #else
101
+ int empty;
102
+ #endif
103
+ };
104
+
105
+ /*
106
+ * xmlRMutex are reentrant mutual exception locks
107
+ */
108
+ struct _xmlRMutex {
109
+ #ifdef HAVE_PTHREAD_H
110
+ pthread_mutex_t lock;
111
+ unsigned int held;
112
+ unsigned int waiters;
113
+ pthread_t tid;
114
+ pthread_cond_t cv;
115
+ #elif defined HAVE_WIN32_THREADS
116
+ CRITICAL_SECTION cs;
117
+ unsigned int count;
118
+ #elif defined HAVE_BEOS_THREADS
119
+ xmlMutexPtr lock;
120
+ thread_id tid;
121
+ int32 count;
122
+ #else
123
+ int empty;
124
+ #endif
125
+ };
126
+
127
+ /*
128
+ * This module still has some internal static data.
129
+ * - xmlLibraryLock a global lock
130
+ * - globalkey used for per-thread data
131
+ */
132
+
133
+ #ifdef HAVE_PTHREAD_H
134
+ static pthread_key_t globalkey;
135
+ static pthread_t mainthread;
136
+ static pthread_once_t once_control = PTHREAD_ONCE_INIT;
137
+ static pthread_once_t once_control_init = PTHREAD_ONCE_INIT;
138
+ static pthread_mutex_t global_init_lock = PTHREAD_MUTEX_INITIALIZER;
139
+ #elif defined HAVE_WIN32_THREADS
140
+ #if defined(HAVE_COMPILER_TLS)
141
+ static __declspec(thread) xmlGlobalState tlstate;
142
+ static __declspec(thread) int tlstate_inited = 0;
143
+ #else /* HAVE_COMPILER_TLS */
144
+ static DWORD globalkey = TLS_OUT_OF_INDEXES;
145
+ #endif /* HAVE_COMPILER_TLS */
146
+ static DWORD mainthread;
147
+ static struct {
148
+ DWORD done;
149
+ LONG control;
150
+ } run_once = { 0, 0};
151
+ static volatile LPCRITICAL_SECTION global_init_lock = NULL;
152
+
153
+ /* endif HAVE_WIN32_THREADS */
154
+ #elif defined HAVE_BEOS_THREADS
155
+ int32 globalkey = 0;
156
+ thread_id mainthread = 0;
157
+ int32 run_once_init = 0;
158
+ static int32 global_init_lock = -1;
159
+ static vint32 global_init_count = 0;
160
+ #endif
161
+
162
+ static xmlRMutexPtr xmlLibraryLock = NULL;
163
+
164
+ #ifdef LIBXML_THREAD_ENABLED
165
+ static void xmlOnceInit(void);
166
+ #endif
167
+
168
+ /**
169
+ * xmlNewMutex:
170
+ *
171
+ * xmlNewMutex() is used to allocate a libxml2 token struct for use in
172
+ * synchronizing access to data.
173
+ *
174
+ * Returns a new simple mutex pointer or NULL in case of error
175
+ */
176
+ xmlMutexPtr
177
+ xmlNewMutex(void)
178
+ {
179
+ xmlMutexPtr tok;
180
+
181
+ if ((tok = malloc(sizeof(xmlMutex))) == NULL)
182
+ return (NULL);
183
+ #ifdef HAVE_PTHREAD_H
184
+ if (libxml_is_threaded != 0)
185
+ pthread_mutex_init(&tok->lock, NULL);
186
+ #elif defined HAVE_WIN32_THREADS
187
+ tok->mutex = CreateMutex(NULL, FALSE, NULL);
188
+ #elif defined HAVE_BEOS_THREADS
189
+ if ((tok->sem = create_sem(1, "xmlMutex")) < B_OK) {
190
+ free(tok);
191
+ return NULL;
192
+ }
193
+ tok->tid = -1;
194
+ #endif
195
+ return (tok);
196
+ }
197
+
198
+ /**
199
+ * xmlFreeMutex:
200
+ * @tok: the simple mutex
201
+ *
202
+ * xmlFreeMutex() is used to reclaim resources associated with a libxml2 token
203
+ * struct.
204
+ */
205
+ void
206
+ xmlFreeMutex(xmlMutexPtr tok)
207
+ {
208
+ if (tok == NULL)
209
+ return;
210
+
211
+ #ifdef HAVE_PTHREAD_H
212
+ if (libxml_is_threaded != 0)
213
+ pthread_mutex_destroy(&tok->lock);
214
+ #elif defined HAVE_WIN32_THREADS
215
+ CloseHandle(tok->mutex);
216
+ #elif defined HAVE_BEOS_THREADS
217
+ delete_sem(tok->sem);
218
+ #endif
219
+ free(tok);
220
+ }
221
+
222
+ /**
223
+ * xmlMutexLock:
224
+ * @tok: the simple mutex
225
+ *
226
+ * xmlMutexLock() is used to lock a libxml2 token.
227
+ */
228
+ void
229
+ xmlMutexLock(xmlMutexPtr tok)
230
+ {
231
+ if (tok == NULL)
232
+ return;
233
+ #ifdef HAVE_PTHREAD_H
234
+ if (libxml_is_threaded != 0)
235
+ pthread_mutex_lock(&tok->lock);
236
+ #elif defined HAVE_WIN32_THREADS
237
+ WaitForSingleObject(tok->mutex, INFINITE);
238
+ #elif defined HAVE_BEOS_THREADS
239
+ if (acquire_sem(tok->sem) != B_NO_ERROR) {
240
+ #ifdef DEBUG_THREADS
241
+ xmlGenericError(xmlGenericErrorContext,
242
+ "xmlMutexLock():BeOS:Couldn't acquire semaphore\n");
243
+ #endif
244
+ }
245
+ tok->tid = find_thread(NULL);
246
+ #endif
247
+
248
+ }
249
+
250
+ /**
251
+ * xmlMutexUnlock:
252
+ * @tok: the simple mutex
253
+ *
254
+ * xmlMutexUnlock() is used to unlock a libxml2 token.
255
+ */
256
+ void
257
+ xmlMutexUnlock(xmlMutexPtr tok)
258
+ {
259
+ if (tok == NULL)
260
+ return;
261
+ #ifdef HAVE_PTHREAD_H
262
+ if (libxml_is_threaded != 0)
263
+ pthread_mutex_unlock(&tok->lock);
264
+ #elif defined HAVE_WIN32_THREADS
265
+ ReleaseMutex(tok->mutex);
266
+ #elif defined HAVE_BEOS_THREADS
267
+ if (tok->tid == find_thread(NULL)) {
268
+ tok->tid = -1;
269
+ release_sem(tok->sem);
270
+ }
271
+ #endif
272
+ }
273
+
274
+ /**
275
+ * xmlNewRMutex:
276
+ *
277
+ * xmlRNewMutex() is used to allocate a reentrant mutex for use in
278
+ * synchronizing access to data. token_r is a re-entrant lock and thus useful
279
+ * for synchronizing access to data structures that may be manipulated in a
280
+ * recursive fashion.
281
+ *
282
+ * Returns the new reentrant mutex pointer or NULL in case of error
283
+ */
284
+ xmlRMutexPtr
285
+ xmlNewRMutex(void)
286
+ {
287
+ xmlRMutexPtr tok;
288
+
289
+ if ((tok = malloc(sizeof(xmlRMutex))) == NULL)
290
+ return (NULL);
291
+ #ifdef HAVE_PTHREAD_H
292
+ if (libxml_is_threaded != 0) {
293
+ pthread_mutex_init(&tok->lock, NULL);
294
+ tok->held = 0;
295
+ tok->waiters = 0;
296
+ pthread_cond_init(&tok->cv, NULL);
297
+ }
298
+ #elif defined HAVE_WIN32_THREADS
299
+ InitializeCriticalSection(&tok->cs);
300
+ tok->count = 0;
301
+ #elif defined HAVE_BEOS_THREADS
302
+ if ((tok->lock = xmlNewMutex()) == NULL) {
303
+ free(tok);
304
+ return NULL;
305
+ }
306
+ tok->count = 0;
307
+ #endif
308
+ return (tok);
309
+ }
310
+
311
+ /**
312
+ * xmlFreeRMutex:
313
+ * @tok: the reentrant mutex
314
+ *
315
+ * xmlRFreeMutex() is used to reclaim resources associated with a
316
+ * reentrant mutex.
317
+ */
318
+ void
319
+ xmlFreeRMutex(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
320
+ {
321
+ if (tok == NULL)
322
+ return;
323
+ #ifdef HAVE_PTHREAD_H
324
+ if (libxml_is_threaded != 0) {
325
+ pthread_mutex_destroy(&tok->lock);
326
+ pthread_cond_destroy(&tok->cv);
327
+ }
328
+ #elif defined HAVE_WIN32_THREADS
329
+ DeleteCriticalSection(&tok->cs);
330
+ #elif defined HAVE_BEOS_THREADS
331
+ xmlFreeMutex(tok->lock);
332
+ #endif
333
+ free(tok);
334
+ }
335
+
336
+ /**
337
+ * xmlRMutexLock:
338
+ * @tok: the reentrant mutex
339
+ *
340
+ * xmlRMutexLock() is used to lock a libxml2 token_r.
341
+ */
342
+ void
343
+ xmlRMutexLock(xmlRMutexPtr tok)
344
+ {
345
+ if (tok == NULL)
346
+ return;
347
+ #ifdef HAVE_PTHREAD_H
348
+ if (libxml_is_threaded == 0)
349
+ return;
350
+
351
+ pthread_mutex_lock(&tok->lock);
352
+ if (tok->held) {
353
+ if (pthread_equal(tok->tid, pthread_self())) {
354
+ tok->held++;
355
+ pthread_mutex_unlock(&tok->lock);
356
+ return;
357
+ } else {
358
+ tok->waiters++;
359
+ while (tok->held)
360
+ pthread_cond_wait(&tok->cv, &tok->lock);
361
+ tok->waiters--;
362
+ }
363
+ }
364
+ tok->tid = pthread_self();
365
+ tok->held = 1;
366
+ pthread_mutex_unlock(&tok->lock);
367
+ #elif defined HAVE_WIN32_THREADS
368
+ EnterCriticalSection(&tok->cs);
369
+ tok->count++;
370
+ #elif defined HAVE_BEOS_THREADS
371
+ if (tok->lock->tid == find_thread(NULL)) {
372
+ tok->count++;
373
+ return;
374
+ } else {
375
+ xmlMutexLock(tok->lock);
376
+ tok->count = 1;
377
+ }
378
+ #endif
379
+ }
380
+
381
+ /**
382
+ * xmlRMutexUnlock:
383
+ * @tok: the reentrant mutex
384
+ *
385
+ * xmlRMutexUnlock() is used to unlock a libxml2 token_r.
386
+ */
387
+ void
388
+ xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
389
+ {
390
+ if (tok == NULL)
391
+ return;
392
+ #ifdef HAVE_PTHREAD_H
393
+ if (libxml_is_threaded == 0)
394
+ return;
395
+
396
+ pthread_mutex_lock(&tok->lock);
397
+ tok->held--;
398
+ if (tok->held == 0) {
399
+ if (tok->waiters)
400
+ pthread_cond_signal(&tok->cv);
401
+ memset(&tok->tid, 0, sizeof(tok->tid));
402
+ }
403
+ pthread_mutex_unlock(&tok->lock);
404
+ #elif defined HAVE_WIN32_THREADS
405
+ if (tok->count > 0) {
406
+ tok->count--;
407
+ LeaveCriticalSection(&tok->cs);
408
+ }
409
+ #elif defined HAVE_BEOS_THREADS
410
+ if (tok->lock->tid == find_thread(NULL)) {
411
+ tok->count--;
412
+ if (tok->count == 0) {
413
+ xmlMutexUnlock(tok->lock);
414
+ }
415
+ return;
416
+ }
417
+ #endif
418
+ }
419
+
420
+ /**
421
+ * xmlGlobalInitMutexLock
422
+ *
423
+ * Makes sure that the global initialization mutex is initialized and
424
+ * locks it.
425
+ */
426
+ void
427
+ __xmlGlobalInitMutexLock(void)
428
+ {
429
+ /* Make sure the global init lock is initialized and then lock it. */
430
+ #ifdef HAVE_PTHREAD_H
431
+ /* The mutex is statically initialized, so we just lock it. */
432
+ #ifdef XML_PTHREAD_WEAK
433
+ if (pthread_mutex_lock == NULL)
434
+ return;
435
+ #endif /* XML_PTHREAD_WEAK */
436
+ pthread_mutex_lock(&global_init_lock);
437
+ #elif defined HAVE_WIN32_THREADS
438
+ LPCRITICAL_SECTION cs;
439
+
440
+ /* Create a new critical section */
441
+ if (global_init_lock == NULL) {
442
+ cs = malloc(sizeof(CRITICAL_SECTION));
443
+ if (cs == NULL) {
444
+ xmlGenericError(xmlGenericErrorContext,
445
+ "xmlGlobalInitMutexLock: out of memory\n");
446
+ return;
447
+ }
448
+ InitializeCriticalSection(cs);
449
+
450
+ /* Swap it into the global_init_lock */
451
+ #ifdef InterlockedCompareExchangePointer
452
+ InterlockedCompareExchangePointer((void **) &global_init_lock,
453
+ cs, NULL);
454
+ #else /* Use older void* version */
455
+ InterlockedCompareExchange((void **) &global_init_lock,
456
+ (void *) cs, NULL);
457
+ #endif /* InterlockedCompareExchangePointer */
458
+
459
+ /* If another thread successfully recorded its critical
460
+ * section in the global_init_lock then discard the one
461
+ * allocated by this thread. */
462
+ if (global_init_lock != cs) {
463
+ DeleteCriticalSection(cs);
464
+ free(cs);
465
+ }
466
+ }
467
+
468
+ /* Lock the chosen critical section */
469
+ EnterCriticalSection(global_init_lock);
470
+ #elif defined HAVE_BEOS_THREADS
471
+ int32 sem;
472
+
473
+ /* Allocate a new semaphore */
474
+ sem = create_sem(1, "xmlGlobalinitMutex");
475
+
476
+ while (global_init_lock == -1) {
477
+ if (atomic_add(&global_init_count, 1) == 0) {
478
+ global_init_lock = sem;
479
+ } else {
480
+ snooze(1);
481
+ atomic_add(&global_init_count, -1);
482
+ }
483
+ }
484
+
485
+ /* If another thread successfully recorded its critical
486
+ * section in the global_init_lock then discard the one
487
+ * allocated by this thread. */
488
+ if (global_init_lock != sem)
489
+ delete_sem(sem);
490
+
491
+ /* Acquire the chosen semaphore */
492
+ if (acquire_sem(global_init_lock) != B_NO_ERROR) {
493
+ #ifdef DEBUG_THREADS
494
+ xmlGenericError(xmlGenericErrorContext,
495
+ "xmlGlobalInitMutexLock():BeOS:Couldn't acquire semaphore\n");
496
+ #endif
497
+ }
498
+ #endif
499
+ }
500
+
501
+ void
502
+ __xmlGlobalInitMutexUnlock(void)
503
+ {
504
+ #ifdef HAVE_PTHREAD_H
505
+ #ifdef XML_PTHREAD_WEAK
506
+ if (pthread_mutex_unlock == NULL)
507
+ return;
508
+ #endif /* XML_PTHREAD_WEAK */
509
+ pthread_mutex_unlock(&global_init_lock);
510
+ #elif defined HAVE_WIN32_THREADS
511
+ if (global_init_lock != NULL) {
512
+ LeaveCriticalSection(global_init_lock);
513
+ }
514
+ #elif defined HAVE_BEOS_THREADS
515
+ release_sem(global_init_lock);
516
+ #endif
517
+ }
518
+
519
+ /**
520
+ * xmlGlobalInitMutexDestroy
521
+ *
522
+ * Makes sure that the global initialization mutex is destroyed before
523
+ * application termination.
524
+ */
525
+ void
526
+ __xmlGlobalInitMutexDestroy(void)
527
+ {
528
+ #ifdef HAVE_PTHREAD_H
529
+ #elif defined HAVE_WIN32_THREADS
530
+ if (global_init_lock != NULL) {
531
+ DeleteCriticalSection(global_init_lock);
532
+ free(global_init_lock);
533
+ global_init_lock = NULL;
534
+ }
535
+ #endif
536
+ }
537
+
538
+ /************************************************************************
539
+ * *
540
+ * Per thread global state handling *
541
+ * *
542
+ ************************************************************************/
543
+
544
+ #ifdef LIBXML_THREAD_ENABLED
545
+ #ifdef xmlLastError
546
+ #undef xmlLastError
547
+ #endif
548
+
549
+ /**
550
+ * xmlFreeGlobalState:
551
+ * @state: a thread global state
552
+ *
553
+ * xmlFreeGlobalState() is called when a thread terminates with a non-NULL
554
+ * global state. It is is used here to reclaim memory resources.
555
+ */
556
+ static void
557
+ xmlFreeGlobalState(void *state)
558
+ {
559
+ xmlGlobalState *gs = (xmlGlobalState *) state;
560
+
561
+ /* free any memory allocated in the thread's xmlLastError */
562
+ xmlResetError(&(gs->xmlLastError));
563
+ free(state);
564
+ }
565
+
566
+ /**
567
+ * xmlNewGlobalState:
568
+ *
569
+ * xmlNewGlobalState() allocates a global state. This structure is used to
570
+ * hold all data for use by a thread when supporting backwards compatibility
571
+ * of libxml2 to pre-thread-safe behaviour.
572
+ *
573
+ * Returns the newly allocated xmlGlobalStatePtr or NULL in case of error
574
+ */
575
+ static xmlGlobalStatePtr
576
+ xmlNewGlobalState(void)
577
+ {
578
+ xmlGlobalState *gs;
579
+
580
+ gs = malloc(sizeof(xmlGlobalState));
581
+ if (gs == NULL) {
582
+ xmlGenericError(xmlGenericErrorContext,
583
+ "xmlGetGlobalState: out of memory\n");
584
+ return (NULL);
585
+ }
586
+
587
+ memset(gs, 0, sizeof(xmlGlobalState));
588
+ xmlInitializeGlobalState(gs);
589
+ return (gs);
590
+ }
591
+ #endif /* LIBXML_THREAD_ENABLED */
592
+
593
+ #ifdef HAVE_PTHREAD_H
594
+ #elif defined HAVE_WIN32_THREADS
595
+ #if !defined(HAVE_COMPILER_TLS)
596
+ #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
597
+ typedef struct _xmlGlobalStateCleanupHelperParams {
598
+ HANDLE thread;
599
+ void *memory;
600
+ } xmlGlobalStateCleanupHelperParams;
601
+
602
+ static void XMLCDECL
603
+ xmlGlobalStateCleanupHelper(void *p)
604
+ {
605
+ xmlGlobalStateCleanupHelperParams *params =
606
+ (xmlGlobalStateCleanupHelperParams *) p;
607
+ WaitForSingleObject(params->thread, INFINITE);
608
+ CloseHandle(params->thread);
609
+ xmlFreeGlobalState(params->memory);
610
+ free(params);
611
+ _endthread();
612
+ }
613
+ #else /* LIBXML_STATIC && !LIBXML_STATIC_FOR_DLL */
614
+
615
+ typedef struct _xmlGlobalStateCleanupHelperParams {
616
+ void *memory;
617
+ struct _xmlGlobalStateCleanupHelperParams *prev;
618
+ struct _xmlGlobalStateCleanupHelperParams *next;
619
+ } xmlGlobalStateCleanupHelperParams;
620
+
621
+ static xmlGlobalStateCleanupHelperParams *cleanup_helpers_head = NULL;
622
+ static CRITICAL_SECTION cleanup_helpers_cs;
623
+
624
+ #endif /* LIBXMLSTATIC && !LIBXML_STATIC_FOR_DLL */
625
+ #endif /* HAVE_COMPILER_TLS */
626
+ #endif /* HAVE_WIN32_THREADS */
627
+
628
+ #if defined HAVE_BEOS_THREADS
629
+
630
+ /**
631
+ * xmlGlobalStateCleanup:
632
+ * @data: unused parameter
633
+ *
634
+ * Used for Beos only
635
+ */
636
+ void
637
+ xmlGlobalStateCleanup(void *data)
638
+ {
639
+ void *globalval = tls_get(globalkey);
640
+
641
+ if (globalval != NULL)
642
+ xmlFreeGlobalState(globalval);
643
+ }
644
+ #endif
645
+
646
+ /**
647
+ * xmlGetGlobalState:
648
+ *
649
+ * xmlGetGlobalState() is called to retrieve the global state for a thread.
650
+ *
651
+ * Returns the thread global state or NULL in case of error
652
+ */
653
+ xmlGlobalStatePtr
654
+ xmlGetGlobalState(void)
655
+ {
656
+ #ifdef HAVE_PTHREAD_H
657
+ xmlGlobalState *globalval;
658
+
659
+ if (libxml_is_threaded == 0)
660
+ return (NULL);
661
+
662
+ pthread_once(&once_control, xmlOnceInit);
663
+
664
+ if ((globalval = (xmlGlobalState *)
665
+ pthread_getspecific(globalkey)) == NULL) {
666
+ xmlGlobalState *tsd = xmlNewGlobalState();
667
+ if (tsd == NULL)
668
+ return(NULL);
669
+
670
+ pthread_setspecific(globalkey, tsd);
671
+ return (tsd);
672
+ }
673
+ return (globalval);
674
+ #elif defined HAVE_WIN32_THREADS
675
+ #if defined(HAVE_COMPILER_TLS)
676
+ if (!tlstate_inited) {
677
+ tlstate_inited = 1;
678
+ xmlInitializeGlobalState(&tlstate);
679
+ }
680
+ return &tlstate;
681
+ #else /* HAVE_COMPILER_TLS */
682
+ xmlGlobalState *globalval;
683
+ xmlGlobalStateCleanupHelperParams *p;
684
+
685
+ xmlOnceInit();
686
+ #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
687
+ globalval = (xmlGlobalState *) TlsGetValue(globalkey);
688
+ #else
689
+ p = (xmlGlobalStateCleanupHelperParams *) TlsGetValue(globalkey);
690
+ globalval = (xmlGlobalState *) (p ? p->memory : NULL);
691
+ #endif
692
+ if (globalval == NULL) {
693
+ xmlGlobalState *tsd = xmlNewGlobalState();
694
+
695
+ if (tsd == NULL)
696
+ return(NULL);
697
+ p = (xmlGlobalStateCleanupHelperParams *)
698
+ malloc(sizeof(xmlGlobalStateCleanupHelperParams));
699
+ if (p == NULL) {
700
+ xmlGenericError(xmlGenericErrorContext,
701
+ "xmlGetGlobalState: out of memory\n");
702
+ xmlFreeGlobalState(tsd);
703
+ return(NULL);
704
+ }
705
+ p->memory = tsd;
706
+ #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
707
+ DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
708
+ GetCurrentProcess(), &p->thread, 0, TRUE,
709
+ DUPLICATE_SAME_ACCESS);
710
+ TlsSetValue(globalkey, tsd);
711
+ _beginthread(xmlGlobalStateCleanupHelper, 0, p);
712
+ #else
713
+ EnterCriticalSection(&cleanup_helpers_cs);
714
+ if (cleanup_helpers_head != NULL) {
715
+ cleanup_helpers_head->prev = p;
716
+ }
717
+ p->next = cleanup_helpers_head;
718
+ p->prev = NULL;
719
+ cleanup_helpers_head = p;
720
+ TlsSetValue(globalkey, p);
721
+ LeaveCriticalSection(&cleanup_helpers_cs);
722
+ #endif
723
+
724
+ return (tsd);
725
+ }
726
+ return (globalval);
727
+ #endif /* HAVE_COMPILER_TLS */
728
+ #elif defined HAVE_BEOS_THREADS
729
+ xmlGlobalState *globalval;
730
+
731
+ xmlOnceInit();
732
+
733
+ if ((globalval = (xmlGlobalState *) tls_get(globalkey)) == NULL) {
734
+ xmlGlobalState *tsd = xmlNewGlobalState();
735
+ if (tsd == NULL)
736
+ return (NULL);
737
+
738
+ tls_set(globalkey, tsd);
739
+ on_exit_thread(xmlGlobalStateCleanup, NULL);
740
+ return (tsd);
741
+ }
742
+ return (globalval);
743
+ #else
744
+ return (NULL);
745
+ #endif
746
+ }
747
+
748
+ /************************************************************************
749
+ * *
750
+ * Library wide thread interfaces *
751
+ * *
752
+ ************************************************************************/
753
+
754
+ /**
755
+ * xmlGetThreadId:
756
+ *
757
+ * xmlGetThreadId() find the current thread ID number
758
+ * Note that this is likely to be broken on some platforms using pthreads
759
+ * as the specification doesn't mandate pthread_t to be an integer type
760
+ *
761
+ * Returns the current thread ID number
762
+ */
763
+ int
764
+ xmlGetThreadId(void)
765
+ {
766
+ #ifdef HAVE_PTHREAD_H
767
+ pthread_t id;
768
+ int ret;
769
+
770
+ if (libxml_is_threaded == 0)
771
+ return (0);
772
+ id = pthread_self();
773
+ /* horrible but preserves compat, see warning above */
774
+ memcpy(&ret, &id, sizeof(ret));
775
+ return (ret);
776
+ #elif defined HAVE_WIN32_THREADS
777
+ return GetCurrentThreadId();
778
+ #elif defined HAVE_BEOS_THREADS
779
+ return find_thread(NULL);
780
+ #else
781
+ return ((int) 0);
782
+ #endif
783
+ }
784
+
785
+ /**
786
+ * xmlIsMainThread:
787
+ *
788
+ * xmlIsMainThread() check whether the current thread is the main thread.
789
+ *
790
+ * Returns 1 if the current thread is the main thread, 0 otherwise
791
+ */
792
+ int
793
+ xmlIsMainThread(void)
794
+ {
795
+ #ifdef HAVE_PTHREAD_H
796
+ if (libxml_is_threaded == -1)
797
+ xmlInitThreads();
798
+ if (libxml_is_threaded == 0)
799
+ return (1);
800
+ pthread_once(&once_control, xmlOnceInit);
801
+ #elif defined HAVE_WIN32_THREADS
802
+ xmlOnceInit();
803
+ #elif defined HAVE_BEOS_THREADS
804
+ xmlOnceInit();
805
+ #endif
806
+
807
+ #ifdef DEBUG_THREADS
808
+ xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n");
809
+ #endif
810
+ #ifdef HAVE_PTHREAD_H
811
+ return (pthread_equal(mainthread,pthread_self()));
812
+ #elif defined HAVE_WIN32_THREADS
813
+ return (mainthread == GetCurrentThreadId());
814
+ #elif defined HAVE_BEOS_THREADS
815
+ return (mainthread == find_thread(NULL));
816
+ #else
817
+ return (1);
818
+ #endif
819
+ }
820
+
821
+ /**
822
+ * xmlLockLibrary:
823
+ *
824
+ * xmlLockLibrary() is used to take out a re-entrant lock on the libxml2
825
+ * library.
826
+ */
827
+ void
828
+ xmlLockLibrary(void)
829
+ {
830
+ #ifdef DEBUG_THREADS
831
+ xmlGenericError(xmlGenericErrorContext, "xmlLockLibrary()\n");
832
+ #endif
833
+ xmlRMutexLock(xmlLibraryLock);
834
+ }
835
+
836
+ /**
837
+ * xmlUnlockLibrary:
838
+ *
839
+ * xmlUnlockLibrary() is used to release a re-entrant lock on the libxml2
840
+ * library.
841
+ */
842
+ void
843
+ xmlUnlockLibrary(void)
844
+ {
845
+ #ifdef DEBUG_THREADS
846
+ xmlGenericError(xmlGenericErrorContext, "xmlUnlockLibrary()\n");
847
+ #endif
848
+ xmlRMutexUnlock(xmlLibraryLock);
849
+ }
850
+
851
+ /**
852
+ * xmlInitThreads:
853
+ *
854
+ * xmlInitThreads() is used to to initialize all the thread related
855
+ * data of the libxml2 library.
856
+ */
857
+ void
858
+ xmlInitThreads(void)
859
+ {
860
+ #ifdef HAVE_PTHREAD_H
861
+ #ifdef XML_PTHREAD_WEAK
862
+ if (libxml_is_threaded == -1) {
863
+ if ((pthread_once != NULL) &&
864
+ (pthread_getspecific != NULL) &&
865
+ (pthread_setspecific != NULL) &&
866
+ (pthread_key_create != NULL) &&
867
+ (pthread_key_delete != NULL) &&
868
+ (pthread_mutex_init != NULL) &&
869
+ (pthread_mutex_destroy != NULL) &&
870
+ (pthread_mutex_lock != NULL) &&
871
+ (pthread_mutex_unlock != NULL) &&
872
+ (pthread_cond_init != NULL) &&
873
+ (pthread_cond_destroy != NULL) &&
874
+ (pthread_cond_wait != NULL) &&
875
+ (pthread_equal != NULL) &&
876
+ (pthread_self != NULL) &&
877
+ (pthread_cond_signal != NULL)) {
878
+ libxml_is_threaded = 1;
879
+
880
+ /* fprintf(stderr, "Running multithreaded\n"); */
881
+ } else {
882
+
883
+ /* fprintf(stderr, "Running without multithread\n"); */
884
+ libxml_is_threaded = 0;
885
+ }
886
+ }
887
+ #endif /* XML_PTHREAD_WEAK */
888
+ #endif
889
+ }
890
+
891
+ /**
892
+ * xmlCleanupThreads:
893
+ *
894
+ * xmlCleanupThreads() is used to to cleanup all the thread related
895
+ * data of the libxml2 library once processing has ended.
896
+ *
897
+ * WARNING: if your application is multithreaded or has plugin support
898
+ * calling this may crash the application if another thread or
899
+ * a plugin is still using libxml2. It's sometimes very hard to
900
+ * guess if libxml2 is in use in the application, some libraries
901
+ * or plugins may use it without notice. In case of doubt abstain
902
+ * from calling this function or do it just before calling exit()
903
+ * to avoid leak reports from valgrind !
904
+ */
905
+ void
906
+ xmlCleanupThreads(void)
907
+ {
908
+ #ifdef DEBUG_THREADS
909
+ xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");
910
+ #endif
911
+ #ifdef HAVE_PTHREAD_H
912
+ if (libxml_is_threaded != 0)
913
+ pthread_key_delete(globalkey);
914
+ once_control = once_control_init;
915
+ #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
916
+ if (globalkey != TLS_OUT_OF_INDEXES) {
917
+ xmlGlobalStateCleanupHelperParams *p;
918
+
919
+ EnterCriticalSection(&cleanup_helpers_cs);
920
+ p = cleanup_helpers_head;
921
+ while (p != NULL) {
922
+ xmlGlobalStateCleanupHelperParams *temp = p;
923
+
924
+ p = p->next;
925
+ xmlFreeGlobalState(temp->memory);
926
+ free(temp);
927
+ }
928
+ cleanup_helpers_head = 0;
929
+ LeaveCriticalSection(&cleanup_helpers_cs);
930
+ TlsFree(globalkey);
931
+ globalkey = TLS_OUT_OF_INDEXES;
932
+ }
933
+ DeleteCriticalSection(&cleanup_helpers_cs);
934
+ #endif
935
+ }
936
+
937
+ #ifdef LIBXML_THREAD_ENABLED
938
+
939
+ /**
940
+ * xmlOnceInit
941
+ *
942
+ * xmlOnceInit() is used to initialize the value of mainthread for use
943
+ * in other routines. This function should only be called using
944
+ * pthread_once() in association with the once_control variable to ensure
945
+ * that the function is only called once. See man pthread_once for more
946
+ * details.
947
+ */
948
+ static void
949
+ xmlOnceInit(void)
950
+ {
951
+ #ifdef HAVE_PTHREAD_H
952
+ (void) pthread_key_create(&globalkey, xmlFreeGlobalState);
953
+ mainthread = pthread_self();
954
+ __xmlInitializeDict();
955
+ #elif defined(HAVE_WIN32_THREADS)
956
+ if (!run_once.done) {
957
+ if (InterlockedIncrement(&run_once.control) == 1) {
958
+ #if !defined(HAVE_COMPILER_TLS)
959
+ #if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)
960
+ InitializeCriticalSection(&cleanup_helpers_cs);
961
+ #endif
962
+ globalkey = TlsAlloc();
963
+ #endif
964
+ mainthread = GetCurrentThreadId();
965
+ __xmlInitializeDict();
966
+ run_once.done = 1;
967
+ } else {
968
+ /* Another thread is working; give up our slice and
969
+ * wait until they're done. */
970
+ while (!run_once.done)
971
+ Sleep(0);
972
+ }
973
+ }
974
+ #elif defined HAVE_BEOS_THREADS
975
+ if (atomic_add(&run_once_init, 1) == 0) {
976
+ globalkey = tls_allocate();
977
+ tls_set(globalkey, NULL);
978
+ mainthread = find_thread(NULL);
979
+ __xmlInitializeDict();
980
+ } else
981
+ atomic_add(&run_once_init, -1);
982
+ #endif
983
+ }
984
+ #endif
985
+
986
+ /**
987
+ * DllMain:
988
+ * @hinstDLL: handle to DLL instance
989
+ * @fdwReason: Reason code for entry
990
+ * @lpvReserved: generic pointer (depends upon reason code)
991
+ *
992
+ * Entry point for Windows library. It is being used to free thread-specific
993
+ * storage.
994
+ *
995
+ * Returns TRUE always
996
+ */
997
+ #ifdef HAVE_PTHREAD_H
998
+ #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
999
+ #if defined(LIBXML_STATIC_FOR_DLL)
1000
+ int XMLCALL
1001
+ xmlDllMain(ATTRIBUTE_UNUSED void *hinstDLL, unsigned long fdwReason,
1002
+ ATTRIBUTE_UNUSED void *lpvReserved)
1003
+ #else
1004
+ /* declare to avoid "no previous prototype for 'DllMain'" warning */
1005
+ /* Note that we do NOT want to include this function declaration in
1006
+ a public header because it's meant to be called by Windows itself,
1007
+ not a program that uses this library. This also has to be exported. */
1008
+
1009
+ XMLPUBFUN BOOL WINAPI
1010
+ DllMain (HINSTANCE hinstDLL,
1011
+ DWORD fdwReason,
1012
+ LPVOID lpvReserved);
1013
+
1014
+ BOOL WINAPI
1015
+ DllMain(ATTRIBUTE_UNUSED HINSTANCE hinstDLL, DWORD fdwReason,
1016
+ ATTRIBUTE_UNUSED LPVOID lpvReserved)
1017
+ #endif
1018
+ {
1019
+ switch (fdwReason) {
1020
+ case DLL_THREAD_DETACH:
1021
+ if (globalkey != TLS_OUT_OF_INDEXES) {
1022
+ xmlGlobalState *globalval = NULL;
1023
+ xmlGlobalStateCleanupHelperParams *p =
1024
+ (xmlGlobalStateCleanupHelperParams *)
1025
+ TlsGetValue(globalkey);
1026
+ globalval = (xmlGlobalState *) (p ? p->memory : NULL);
1027
+ if (globalval) {
1028
+ xmlFreeGlobalState(globalval);
1029
+ TlsSetValue(globalkey, NULL);
1030
+ }
1031
+ if (p) {
1032
+ EnterCriticalSection(&cleanup_helpers_cs);
1033
+ if (p == cleanup_helpers_head)
1034
+ cleanup_helpers_head = p->next;
1035
+ else
1036
+ p->prev->next = p->next;
1037
+ if (p->next != NULL)
1038
+ p->next->prev = p->prev;
1039
+ LeaveCriticalSection(&cleanup_helpers_cs);
1040
+ free(p);
1041
+ }
1042
+ }
1043
+ break;
1044
+ }
1045
+ return TRUE;
1046
+ }
1047
+ #endif
1048
+ #define bottom_threads
1049
+ #include "elfgcchack.h"