static __declspec(thread) xmlGlobalState tlstate;
static __declspec(thread) int tlstate_inited = 0;
#else /* HAVE_COMPILER_TLS */
-static DWORD globalkey;
+static DWORD globalkey = TLS_OUT_OF_INDEXES;
#endif /* HAVE_COMPILER_TLS */
static DWORD mainthread;
static int run_once_init = 1;
void
xmlFreeMutex(xmlMutexPtr tok)
{
+ if (tok == NULL) return;
+
#ifdef HAVE_PTHREAD_H
pthread_mutex_destroy(&tok->lock);
#elif defined HAVE_WIN32_THREADS
* xmlMutexLock() is used to lock a libxml2 token.
*/
void
-xmlMutexLock(xmlMutexPtr tok ATTRIBUTE_UNUSED)
+xmlMutexLock(xmlMutexPtr tok)
{
+ if (tok == NULL)
+ return;
#ifdef HAVE_PTHREAD_H
pthread_mutex_lock(&tok->lock);
#elif defined HAVE_WIN32_THREADS
pthread_mutex_init(&tok->lock, NULL);
tok->held = 0;
tok->waiters = 0;
+ pthread_cond_init(&tok->cv, NULL);
#elif defined HAVE_WIN32_THREADS
InitializeCriticalSection(&tok->cs);
tok->count = 0;
#ifdef HAVE_WIN32_THREADS
-#if !defined(HAVE_COMPILER_TLS)
+#if !defined(HAVE_COMPILER_TLS) && defined(LIBXML_STATIC)
typedef struct _xmlGlobalStateCleanupHelperParams
{
HANDLE thread;
free(params);
_endthread();
}
-#endif /* HAVE_COMPILER_TLS */
+#endif /* HAVE_COMPILER_TLS && LIBXML_STATIC */
#endif /* HAVE_WIN32_THREADS */
/**
}
if ((globalval = (xmlGlobalState *) TlsGetValue(globalkey)) == NULL) {
xmlGlobalState *tsd = xmlNewGlobalState();
+#if defined(LIBXML_STATIC)
xmlGlobalStateCleanupHelperParams *p =
(xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams));
p->memory = tsd;
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &p->thread, 0, TRUE, DUPLICATE_SAME_ACCESS);
+#endif
TlsSetValue(globalkey, tsd);
+#if defined(LIBXML_STATIC)
_beginthread(xmlGlobalStateCleanupHelper, 0, p);
+#endif
return (tsd);
}
mainthread = GetCurrentThreadId();
#endif
}
+
+/**
+ * DllMain
+ *
+ * Entry point for Windows library. It is being used to free thread-specific
+ * storage.
+ */
+#if defined(HAVE_WIN32_THREADS) && !defined(LIBXML_STATIC)
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ switch(fdwReason) {
+ case DLL_THREAD_DETACH:
+ if (globalkey != TLS_OUT_OF_INDEXES) {
+ xmlGlobalState *globalval = (xmlGlobalState *)TlsGetValue(globalkey);
+ if (globalval) {
+ xmlFreeGlobalState(globalval);
+ TlsSetValue(globalkey, NULL);
+ }
+ }
+ break;
+ case DLL_PROCESS_DETACH:
+ if (globalkey != TLS_OUT_OF_INDEXES) {
+ TlsFree(globalkey);
+ globalkey = TLS_OUT_OF_INDEXES;
+ }
+ break;
+ }
+ return TRUE;
+}
+#endif
+