updated libxml2 to 2.5.10
[TestXSLT.git] / libxml2 / threads.c
index 6aa5ecc..8e7a08c 100644 (file)
@@ -92,7 +92,7 @@ static pthread_once_t once_control = PTHREAD_ONCE_INIT;
 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;
@@ -134,6 +134,8 @@ xmlNewMutex(void)
 void
 xmlFreeMutex(xmlMutexPtr tok)
 {
+    if (tok == NULL) return;
+
 #ifdef HAVE_PTHREAD_H
     pthread_mutex_destroy(&tok->lock);
 #elif defined HAVE_WIN32_THREADS
@@ -149,8 +151,10 @@ xmlFreeMutex(xmlMutexPtr tok)
  * 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
@@ -196,6 +200,7 @@ xmlNewRMutex(void)
     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;
@@ -323,7 +328,7 @@ xmlNewGlobalState(void)
 
 
 #ifdef HAVE_WIN32_THREADS
-#if !defined(HAVE_COMPILER_TLS)
+#if !defined(HAVE_COMPILER_TLS) && defined(LIBXML_STATIC)
 typedef struct _xmlGlobalStateCleanupHelperParams
 {
     HANDLE thread;
@@ -339,7 +344,7 @@ static void xmlGlobalStateCleanupHelper (void *p)
     free(params);
     _endthread();
 }
-#endif /* HAVE_COMPILER_TLS */
+#endif /* HAVE_COMPILER_TLS && LIBXML_STATIC */
 #endif /* HAVE_WIN32_THREADS */
 
 /**
@@ -381,13 +386,17 @@ xmlGetGlobalState(void)
     }
     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);
     }
@@ -535,3 +544,34 @@ xmlOnceInit(void) {
     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
+