applied patch from Marcin 'Shard' Konicki to provide BeOS thread support.

* nanoftp.c nanohttp.c testThreads.c threads.c: applied patch from
  Marcin 'Shard' Konicki to provide BeOS thread support.
Daniel
diff --git a/ChangeLog b/ChangeLog
index df97fd8..942f4b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Oct 29 14:37:40 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* nanoftp.c nanohttp.c testThreads.c threads.c: applied patch from
+	  Marcin 'Shard' Konicki to provide BeOS thread support.
+
 Wed Oct 29 14:20:14 CET 2003 Daniel Veillard <daniel@veillard.com>
 
 	* xmlschemas.c include/libxml/xmlschemas.h: applied patch
diff --git a/nanoftp.c b/nanoftp.c
index 5ea71f7..c181728 100644
--- a/nanoftp.c
+++ b/nanoftp.c
@@ -2221,10 +2221,10 @@
 void ftpData(void *userData, const char *data, int len) {
     if (userData == NULL) return;
     if (len <= 0) {
-	fclose(userData);
+	fclose((FILE*)userData);
 	return;
     }	
-    fwrite(data, len, 1, userData);
+    fwrite(data, len, 1, (FILE*)userData);
 }
 
 int main(int argc, char **argv) {
diff --git a/nanohttp.c b/nanohttp.c
index 489f14a..a1f13dc 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -1314,7 +1314,7 @@
     if (contentType && *contentType)
 	blen += strlen(*contentType) + 16;
     blen += strlen(method) + strlen(ctxt->path) + 24;
-    bp = xmlMallocAtomic(blen);
+    bp = (char*)xmlMallocAtomic(blen);
     if ( bp == NULL ) {
         xmlNanoHTTPFreeCtxt( ctxt );
 	xmlHTTPErrMemory("allocating header buffer");
@@ -1616,7 +1616,7 @@
  */
 int
 xmlNanoHTTPContentLength( void * ctx ) {
-    xmlNanoHTTPCtxtPtr	ctxt = ctx;
+    xmlNanoHTTPCtxtPtr	ctxt = (xmlNanoHTTPCtxtPtr)ctx;
 
     return ( ( ctxt == NULL ) ? -1 : ctxt->ContentLength );
 }
@@ -1631,7 +1631,7 @@
  */
 const char *
 xmlNanoHTTPRedir( void * ctx ) {
-    xmlNanoHTTPCtxtPtr	ctxt = ctx;
+    xmlNanoHTTPCtxtPtr	ctxt = (xmlNanoHTTPCtxtPtr)ctx;
 
     return ( ( ctxt == NULL ) ? NULL : ctxt->location );
 }
@@ -1646,7 +1646,7 @@
  */
 const char *
 xmlNanoHTTPEncoding( void * ctx ) {
-    xmlNanoHTTPCtxtPtr	ctxt = ctx;
+    xmlNanoHTTPCtxtPtr	ctxt = (xmlNanoHTTPCtxtPtr)ctx;
 
     return ( ( ctxt == NULL ) ? NULL : ctxt->encoding );
 }
@@ -1661,7 +1661,7 @@
  */
 const char *
 xmlNanoHTTPMimeType( void * ctx ) {
-    xmlNanoHTTPCtxtPtr	ctxt = ctx;
+    xmlNanoHTTPCtxtPtr	ctxt = (xmlNanoHTTPCtxtPtr)ctx;
 
     return ( ( ctxt == NULL ) ? NULL : ctxt->mimeType );
 }
@@ -1680,7 +1680,7 @@
  */
 int
 xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len ) {
-    xmlNanoHTTPCtxtPtr	ctxt = ctx;
+    xmlNanoHTTPCtxtPtr	ctxt = (xmlNanoHTTPCtxtPtr)ctx;
 
     int			rc = 0;
     int			cur_lgth;
diff --git a/testThreads.c b/testThreads.c
index 24633ee..d740a14 100644
--- a/testThreads.c
+++ b/testThreads.c
@@ -7,7 +7,11 @@
 #include <libxml/threads.h>
 #include <libxml/parser.h>
 #include <libxml/catalog.h>
+#ifdef HAVE_PTHREAD_H
 #include <pthread.h>
+#elif defined HAVE_BEOS_THREADS
+#include <OS.h>
+#endif
 #include <string.h>
 #if !defined(_MSC_VER)
 #include <unistd.h>
@@ -15,7 +19,11 @@
 #include <assert.h>
 
 #define	MAX_ARGC	20
+#ifdef HAVE_PTHREAD_H
 static pthread_t tid[MAX_ARGC];
+#elif defined HAVE_BEOS_THREADS
+static thread_id tid[MAX_ARGC];
+#endif
 
 static const char *catalog = "test/threads/complex.xml";
 static const char *testfiles[] = {
@@ -83,6 +91,7 @@
     return ((void *) Okay);
 }
 
+#ifdef HAVE_PTHREAD_H
 int
 main(void)
 {
@@ -125,6 +134,62 @@
     xmlMemoryDump();
     return (0);
 }
+#elif defined HAVE_BEOS_THREADS
+int
+main(void)
+{
+    unsigned int i, repeat;
+    unsigned int num_threads = sizeof(testfiles) / sizeof(testfiles[0]);
+    void *results[MAX_ARGC];
+    status_t ret;
+
+    xmlInitParser();
+    printf("Parser initialized\n");
+    for (repeat = 0;repeat < 500;repeat++) {
+    printf("repeat: %d\n",repeat);
+	xmlLoadCatalog(catalog);
+	printf("loaded catalog: %s\n", catalog);
+	for (i = 0; i < num_threads; i++) {
+	    results[i] = NULL;
+	    tid[i] = (thread_id) -1;
+	}
+	printf("cleaned threads\n");
+	for (i = 0; i < num_threads; i++) {
+		tid[i] = spawn_thread(thread_specific_data, "xmlTestThread", B_NORMAL_PRIORITY, (void *) testfiles[i]);
+		if (tid[i] < B_OK) {
+			perror("beos_thread_create");
+			exit(1);
+		}
+		printf("beos_thread_create %d -> %d\n", i, tid[i]);
+	}
+	for (i = 0; i < num_threads; i++) {
+	    ret = wait_for_thread(tid[i], &results[i]);
+	    printf("beos_thread_wait %d -> %d\n", i, ret);
+	    if (ret != B_OK) {
+			perror("beos_thread_wait");
+			exit(1);
+	    }
+	}
+
+	xmlCatalogCleanup();
+	ret = B_OK;
+	for (i = 0; i < num_threads; i++)
+	    if (results[i] != (void *) Okay) {
+			printf("Thread %d handling %s failed\n", i, testfiles[i]);
+			ret = B_ERROR;
+		}
+    }
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+	if (ret == B_OK)
+		printf("testThread : BeOS : SUCCESS!\n");
+	else
+		printf("testThread : BeOS : FAILED!\n");
+
+    return (0);
+}
+#endif /* pthreads or BeOS threads */
 
 #else /* !LIBXML_THREADS_ENABLED */
 int
diff --git a/threads.c b/threads.c
index a17ea2f..2f174e2 100644
--- a/threads.c
+++ b/threads.c
@@ -35,6 +35,11 @@
 #endif
 #endif
 
+#ifdef HAVE_BEOS_THREADS
+#include <OS.h>
+#include <TLS.h>
+#endif
+
 #if defined(SOLARIS)
 #include <note.h>
 #endif
@@ -55,6 +60,8 @@
     pthread_mutex_t lock;
 #elif defined HAVE_WIN32_THREADS
     HANDLE mutex;
+#elif defined HAVE_BEOS_THREADS
+	sem_id sem;
 #else
     int empty;
 #endif
@@ -73,6 +80,10 @@
 #elif defined HAVE_WIN32_THREADS
     CRITICAL_SECTION cs;
     unsigned int count;
+#elif defined HAVE_BEOS_THREADS
+	xmlMutexPtr lock;
+	thread_id tid;
+	int32 count;
 #else
     int empty;
 #endif
@@ -96,7 +107,12 @@
 #endif /* HAVE_COMPILER_TLS */
 static DWORD mainthread;
 static int run_once_init = 1;
-#endif /* HAVE_WIN32_THREADS */
+/* endif HAVE_WIN32_THREADS */
+#elif defined HAVE_BEOS_THREADS
+int32 globalkey = 0;
+thread_id mainthread = 0;
+int32 run_once_init = 0;
+#endif
 
 static xmlRMutexPtr	xmlLibraryLock = NULL;
 #ifdef LIBXML_THREAD_ENABLED
@@ -122,6 +138,11 @@
     pthread_mutex_init(&tok->lock, NULL);
 #elif defined HAVE_WIN32_THREADS
     tok->mutex = CreateMutex(NULL, FALSE, NULL);
+#elif defined HAVE_BEOS_THREADS
+	if ((tok->sem = create_sem(1, "xmlMutex")) < B_OK) {
+		free(tok);
+		return NULL;
+	}
 #endif
     return (tok);
 }
@@ -142,6 +163,8 @@
     pthread_mutex_destroy(&tok->lock);
 #elif defined HAVE_WIN32_THREADS
     CloseHandle(tok->mutex);
+#elif defined HAVE_BEOS_THREADS
+	delete_sem(tok->sem);
 #endif
     free(tok);
 }
@@ -161,6 +184,13 @@
     pthread_mutex_lock(&tok->lock);
 #elif defined HAVE_WIN32_THREADS
     WaitForSingleObject(tok->mutex, INFINITE);
+#elif defined HAVE_BEOS_THREADS
+	if (acquire_sem(tok->sem) != B_NO_ERROR) {
+#ifdef DEBUG_THREADS
+		xmlGenericError(xmlGenericErrorContext, "xmlMutexLock():BeOS:Couldn't aquire semaphore\n");
+		exit();
+#endif
+	}
 #endif
 
 }
@@ -180,6 +210,8 @@
     pthread_mutex_unlock(&tok->lock);
 #elif defined HAVE_WIN32_THREADS
     ReleaseMutex(tok->mutex);
+#elif defined HAVE_BEOS_THREADS
+	release_sem(tok->sem);
 #endif
 }
 
@@ -208,6 +240,13 @@
 #elif defined HAVE_WIN32_THREADS
     InitializeCriticalSection(&tok->cs);
     tok->count = 0;
+#elif defined HAVE_BEOS_THREADS
+	if ((tok->lock = xmlNewMutex()) == NULL) {
+		free(tok);
+		return NULL;
+	}
+	tok->count = 0;
+	tok->tid = 0;
 #endif
     return (tok);
 }
@@ -226,6 +265,8 @@
     pthread_mutex_destroy(&tok->lock);
 #elif defined HAVE_WIN32_THREADS
     DeleteCriticalSection(&tok->cs);
+#elif defined HAVE_BEOS_THREADS
+	xmlFreeMutex(tok->lock);
 #endif
     free(tok);
 }
@@ -261,6 +302,15 @@
 #elif defined HAVE_WIN32_THREADS
     EnterCriticalSection(&tok->cs);
     ++tok->count;
+#elif defined HAVE_BEOS_THREADS
+	if (tok->tid == find_thread(NULL)) {
+		tok->count++;
+		return;
+	} else {
+		xmlMutexLock(tok->lock);
+		tok->tid = find_thread(NULL);
+		tok->count = 1;
+	}
 #endif
 }
 
@@ -287,6 +337,15 @@
 #elif defined HAVE_WIN32_THREADS
     if (!--tok->count) 
 	LeaveCriticalSection(&tok->cs);
+#elif defined HAVE_BEOS_THREADS
+	if (tok->tid == find_thread(NULL)) {
+		tok->count--;
+		if (tok->count == 0) {
+			tok->tid = 0;
+			xmlMutexUnlock(tok->lock);
+		}
+		return;
+	}
 #endif
 }
 
@@ -369,6 +428,15 @@
 #endif /* HAVE_COMPILER_TLS */
 #endif /* HAVE_WIN32_THREADS */
 
+#if defined HAVE_BEOS_THREADS
+void xmlGlobalStateCleanup(void *data)
+{
+	void *globalval = tls_get(globalkey);
+	if (globalval != NULL)
+		xmlFreeGlobalState(globalval);
+}
+#endif
+
 /**
  * xmlGetGlobalState:
  *
@@ -438,6 +506,20 @@
     }
     return (globalval);
 #endif /* HAVE_COMPILER_TLS */
+#elif defined HAVE_BEOS_THREADS
+    xmlGlobalState *globalval;
+
+    xmlOnceInit();
+
+    if ((globalval = (xmlGlobalState *)
+		tls_get(globalkey)) == NULL) {
+        xmlGlobalState *tsd = xmlNewGlobalState();
+
+        tls_set(globalkey, tsd);
+        on_exit_thread(xmlGlobalStateCleanup, NULL);
+        return (tsd);
+    }
+    return (globalval);
 #else
     return(NULL);
 #endif
@@ -463,6 +545,8 @@
     return((int) pthread_self());
 #elif defined HAVE_WIN32_THREADS
     return GetCurrentThreadId();
+#elif defined HAVE_BEOS_THREADS
+	return find_thread(NULL);
 #else
     return((int) 0);
 #endif
@@ -485,6 +569,8 @@
 	run_once_init = 0; 
 	xmlOnceInit (); 
     }
+#elif defined HAVE_BEOS_THREADS
+	xmlOnceInit();
 #endif
         
 #ifdef DEBUG_THREADS
@@ -494,6 +580,8 @@
     return(mainthread == pthread_self());
 #elif defined HAVE_WIN32_THREADS
     return(mainthread == GetCurrentThreadId ());
+#elif defined HAVE_BEOS_THREADS
+	return(mainthread == find_thread(NULL));
 #else
     return(1);
 #endif
@@ -601,6 +689,15 @@
 #endif
     mainthread = GetCurrentThreadId();
 #endif
+
+#ifdef HAVE_BEOS_THREADS
+	if (atomic_add(&run_once_init, 1) == 0) {
+		globalkey = tls_allocate();
+		tls_set(globalkey, NULL);
+		mainthread = find_thread(NULL);
+	} else
+		atomic_add(&run_once_init, -1);
+#endif
 }
 #endif