I've had a look at Eugene's changes. They make sense, but didn't quite address my needs. I've attached a proposed patch against the 2.5.8 source; I'd like feedback on a number of questions before it's committed. Here's how it differs from the 2.5.8 version. a) A new macro controls conditional compilation (LIBXML_STATIC_FOR_DLL as per Stéphane's suggestion). b) If the library is compiled into a DLL (whether because LIBXML_STATIC is undefined or because LIBXML_STATIC_FOR_DLL is defined): - a linked list of the thread-local "global" data is maintained; - operations on the list are synchronized with a critical section; - thread-local data is released in DllMain() if LIBXML_STATIC is undefined, otherwise in xmlCleanupThreads(); The critical section is initialized and cleaned up in DllMain() if LIBXML_STATIC is undefined, otherwise in xmlInitThreads() and xmlCleanupThreads(). c) If the library is NOT compiled into a DLL (LIBXML_STATIC is defined, LIBXML_STATIC_FOR_DLL is not), the watchdog thread is still used. I also found made DllMain() conditional on !HAVE_COMPILER_TLS. I did this to make it compile with all combinations of macros defined, but I think it makes sense. My questions (for Stéphane, Igor, and anyone else with an informed point of view): 1) Is LIBXML_STATIC_FOR_DLL a suitable name? 2) Should the critical section always get set up and torn down in xmlInitThreads() and xmlCleanupThreads()? As things stand, it's done in DllMain() if libxml is a DLL. I like the idea of doing it in one place, but this introduces the possibility that the CS won't be initialized when it's needed if xmlInitParser() isn't called. 2a) If DllMain() continues to set up and tear down the CS, should the code be factored out into separate function, since it's identical? 3) Is it sensible and permissible to do the CS setup and tear down in xmlInitThreads() and xmlCleanupThreads()? They currently do nothing, so I'm not sure I'm using them appropriately. 4) Any coding style fax pas?
Attachment:
threads.c.diff
Description: Binary data