Partial patch from SF #452266, by Jason Petrone.

This changes Pythread_start_thread() to return the thread ID, or -1
for an error.  (It's technically an incompatible API change, but I
doubt anyone calls it.)
diff --git a/Python/thread.c b/Python/thread.c
index 3558af0..df42f31 100644
--- a/Python/thread.c
+++ b/Python/thread.c
@@ -111,7 +111,6 @@
 
 #ifdef HAVE_PTH
 #include "thread_pth.h"
-#undef _POSIX_THREADS
 #endif
 
 #ifdef _POSIX_THREADS
diff --git a/Python/thread_beos.h b/Python/thread_beos.h
index 046d37e..3f84347 100644
--- a/Python/thread_beos.h
+++ b/Python/thread_beos.h
@@ -112,7 +112,7 @@
 
 static int32 thread_count = 0;
 
-int PyThread_start_new_thread( void (*func)(void *), void *arg )
+long PyThread_start_new_thread( void (*func)(void *), void *arg )
 {
 	status_t success = 0;
 	thread_id tid;
@@ -131,7 +131,7 @@
 		success = resume_thread( tid );
 	}
 
-	return ( success == B_NO_ERROR ? 1 : 0 );
+	return ( success == B_NO_ERROR ? tid : -1 );
 }
 
 long PyThread_get_thread_ident( void )
diff --git a/Python/thread_cthread.h b/Python/thread_cthread.h
index 0805051..8487cc2 100644
--- a/Python/thread_cthread.h
+++ b/Python/thread_cthread.h
@@ -14,7 +14,7 @@
 /*
  * Thread support.
  */
-int
+long
 PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
 	int success = 0;	/* init not needed when SOLARIS_THREADS and */
@@ -27,7 +27,7 @@
 	 * so well do it here
 	 */
 	cthread_detach(cthread_fork((cthread_fn_t) func, arg));
-	return success < 0 ? 0 : 1;
+	return success < 0 ? -1 : 0;
 }
 
 long
diff --git a/Python/thread_foobar.h b/Python/thread_foobar.h
index 6edd0f9..4baf7e7 100644
--- a/Python/thread_foobar.h
+++ b/Python/thread_foobar.h
@@ -10,7 +10,7 @@
 /*
  * Thread support.
  */
-int
+long
 PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
 	int success = 0;	/* init not needed when SOLARIS_THREADS and */
@@ -19,7 +19,7 @@
 	dprintf(("PyThread_start_new_thread called\n"));
 	if (!initialized)
 		PyThread_init_thread();
-	return success < 0 ? 0 : 1;
+	return success < 0 ? -1 : 0;
 }
 
 long
diff --git a/Python/thread_lwp.h b/Python/thread_lwp.h
index bf44e04..f6e6885 100644
--- a/Python/thread_lwp.h
+++ b/Python/thread_lwp.h
@@ -26,7 +26,7 @@
  */
 
 
-int PyThread_start_new_thread(void (*func)(void *), void *arg)
+long PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
 	thread_t tid;
 	int success;
@@ -34,7 +34,7 @@
 	if (!initialized)
 		PyThread_init_thread();
 	success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg);
-	return success < 0 ? 0 : 1;
+	return success < 0 ? -1 : 0;
 }
 
 long PyThread_get_thread_ident(void)
diff --git a/Python/thread_nt.h b/Python/thread_nt.h
index 1d27627..21aac29 100644
--- a/Python/thread_nt.h
+++ b/Python/thread_nt.h
@@ -5,6 +5,7 @@
 #include <windows.h>
 #include <limits.h>
 #include <process.h>
+#include <Python.h>
 
 typedef struct NRMUTEX {
 	LONG   owned ;
@@ -12,6 +13,8 @@
 	HANDLE hevent ;
 } NRMUTEX, *PNRMUTEX ;
 
+/* dictionary to correlate thread ids with the handle needed to terminate them*/
+static PyObject *threads = NULL;
 
 typedef PVOID WINAPI interlocked_cmp_xchg_t(PVOID *dest, PVOID exc, PVOID comperand) ;
 
@@ -145,28 +148,67 @@
  */
 static void PyThread__init_thread(void)
 {
+	threads = PyDict_New();
 }
 
 /*
  * Thread support.
  */
-int PyThread_start_new_thread(void (*func)(void *), void *arg)
+
+typedef struct {
+	void (*func)(void*);
+	void *arg;			
+	long id;
+	HANDLE done;
+} callobj;
+
+static int
+bootstrap(void *call)
+{
+	callobj *obj = (callobj*)call;
+	/* copy callobj since other thread might free it before we're done */
+	void (*func)(void*) = obj->func;
+	void *arg = obj->arg;
+
+	obj->id = PyThread_get_thread_ident();
+	ReleaseSemaphore(obj->done, 1, NULL);
+	func(arg);
+	return 0;
+}
+
+long PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
 	unsigned long rv;
 	int success = 0;
+	callobj *obj;
+	int id;
+	PyObject *key, *val;
 
 	dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident()));
 	if (!initialized)
 		PyThread_init_thread();
 
-	rv = _beginthread(func, 0, arg); /* use default stack size */
+	obj = malloc(sizeof(callobj)); 
+	obj->func = func;
+	obj->arg = arg;
+	obj->done = CreateSemaphore(NULL, 0, 1, NULL);
+
+	rv = _beginthread(func, 0, obj); /* use default stack size */
  
 	if (rv != (unsigned long)-1) {
 		success = 1;
 		dprintf(("%ld: PyThread_start_new_thread succeeded: %p\n", PyThread_get_thread_ident(), rv));
 	}
 
-	return success;
+	/* wait for thread to initialize and retrieve id */
+	WaitForSingleObject(obj->done, 5000);  /* maybe INFINITE instead of 5000? */
+	CloseHandle((HANDLE)obj->done);
+	key = PyLong_FromLong(obj->id);
+	val = PyLong_FromLong((long)rv);
+	PyDict_SetItem(threads, key, val);
+	id = obj->id;
+	free(obj);
+	return id;
 }
 
 /*
diff --git a/Python/thread_os2.h b/Python/thread_os2.h
index 3f913c5..31800d6 100644
--- a/Python/thread_os2.h
+++ b/Python/thread_os2.h
@@ -21,16 +21,16 @@
 /*
  * Thread support.
  */
-int
+long
 PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
   int aThread;
-  int success = 1;
+  int success = 0;
 
   aThread = _beginthread(func,NULL,65536,arg);
 
   if( aThread == -1 ) {
-    success = 0;
+    success = -1;
     fprintf(stderr,"aThread failed == %d",aThread);
     dprintf(("_beginthread failed. return %ld\n", errno));
   }
diff --git a/Python/thread_pth.h b/Python/thread_pth.h
index 6596b1a..71e0d04 100644
--- a/Python/thread_pth.h
+++ b/Python/thread_pth.h
@@ -44,7 +44,7 @@
  */
 
 
-int PyThread_start_new_thread(void (*func)(void *), void *arg)
+long PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
 	pth_t th;
 	dprintf(("PyThread_start_new_thread called\n"));
@@ -56,7 +56,7 @@
 				 (void *)arg
 				 );
 
-	return th == NULL ? 0 : 1;
+	return th;
 }
 
 long PyThread_get_thread_ident(void)
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index 7170c8a..0fbafda 100644
--- a/Python/thread_pthread.h
+++ b/Python/thread_pthread.h
@@ -143,7 +143,7 @@
  */
 
 
-int 
+long
 PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
 	pthread_t th;
@@ -210,7 +210,11 @@
 		pthread_detach(th);
 #endif
 	}
-	return success != 0 ? 0 : 1;
+#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
+	return (long) th;
+#else
+	return (long) *(long *) &th;
+#endif
 }
 
 /* XXX This implementation is considered (to quote Tim Peters) "inherently
diff --git a/Python/thread_sgi.h b/Python/thread_sgi.h
index 863284e..eda7972 100644
--- a/Python/thread_sgi.h
+++ b/Python/thread_sgi.h
@@ -168,7 +168,7 @@
 	}
 }
 
-int PyThread_start_new_thread(void (*func)(void *), void *arg)
+long PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
 #ifdef USE_DL
 	long addr, size;
@@ -223,7 +223,7 @@
 	}
 	if (usunsetlock(count_lock) < 0)
 		perror("usunsetlock (count_lock)");
-	return success < 0 ? 0 : 1;
+	return success;
 }
 
 long PyThread_get_thread_ident(void)
diff --git a/Python/thread_solaris.h b/Python/thread_solaris.h
index 66bdfa2..4c958b9 100644
--- a/Python/thread_solaris.h
+++ b/Python/thread_solaris.h
@@ -36,9 +36,10 @@
 }
 
 
-int 
+long
 PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
+	thread_t tid;
 	struct func_arg *funcarg;
 	int success = 0;	/* init not needed when SOLARIS_THREADS and */
 				/* C_THREADS implemented properly */
@@ -50,12 +51,12 @@
 	funcarg->func = func;
 	funcarg->arg = arg;
 	if (thr_create(0, 0, new_func, funcarg,
-		       THR_DETACHED | THR_NEW_LWP, 0)) {
+		       THR_DETACHED | THR_NEW_LWP, &tid)) {
 		perror("thr_create");
 		free((void *) funcarg);
 		success = -1;
 	}
-	return success < 0 ? 0 : 1;
+	return tid;
 }
 
 long
diff --git a/Python/thread_wince.h b/Python/thread_wince.h
index 3790bda..b5129b2 100644
--- a/Python/thread_wince.h
+++ b/Python/thread_wince.h
@@ -22,10 +22,10 @@
 /*
  * Thread support.
  */
-int PyThread_start_new_thread(void (*func)(void *), void *arg)
+long PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
 	long rv;
-	int success = 0;
+	int success = -1;
 
 	dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident()));
 	if (!initialized)
@@ -34,7 +34,7 @@
 	rv = _beginthread(func, 0, arg); /* use default stack size */
  
 	if (rv != -1) {
-		success = 1;
+		success = 0;
 		dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident()));
 	}