[patch] a patch to kill a thread in any OS

anton wilson anton.wilson at camotion.com
Wed Feb 19 19:09:06 EST 2003


In a previous thread last week, there was some discussion about
killing a python thread by making it throw a SystemExit exception
from within the interpreter loop. I've implemented it this way:

1. Each thread gets a global tid number assigned by python when created
   and passed to t_bootstate an argument
2. Adding a new method thread.kill_thread(tid) to request that a thread 
   die
3. Make the thread.start_new() return the python assigned tid
4. Adding a hashtable of threads to be killed that is checked every x   
   bytecodes before it tries to release the GIL.If the tstate->id is in 
   the hashtable, throw the SystemExit Exception. I've made the 
   following patch for every OS, but it has only been tested on Linux.

It works without problem so far.

Possible changes:

Make the thread id be the actual tid or pid instead of a global python
tid. 

Anton Wilson
Camotion Inc.



///////BEGIN PATCH HERE ////////


diff -r -u Python-2.2.2/Include/ceval.h
Python-2.2.2moremod/Include/ceval.h
--- Python-2.2.2/Include/ceval.h	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Include/ceval.h	2003-02-19 18:02:08.000000000
-0500
@@ -4,6 +4,19 @@
 extern "C" {
 #endif

+#include <sys/types.h>
+struct tidnode{
+  
+  long tid;
+  struct tidnode *prev;
+  struct tidnode *next;
+
+};
+
+DL_IMPORT(long) PyEval_get_thread_ident(void);
+DL_IMPORT(int) PyEval_AddTid( long );
+DL_IMPORT(void) PyEval_IncrementTid(void);
+DL_IMPORT(int) PyEval_GetTid(void);
 
 /* Interface to random parts in ceval.c */
 
diff -r -u Python-2.2.2/Include/pystate.h
Python-2.2.2moremod/Include/pystate.h
--- Python-2.2.2/Include/pystate.h	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Include/pystate.h	2003-02-19 17:44:54.000000000
-0500
@@ -68,8 +68,9 @@
     PyObject *exc_traceback;

     PyObject *dict;
-
     int tick_counter;
+    long id;
+

     /* XXX signal handlers should also be here */

@@ -80,7 +81,7 @@
 DL_IMPORT(void) PyInterpreterState_Clear(PyInterpreterState *);
 DL_IMPORT(void) PyInterpreterState_Delete(PyInterpreterState *);
 
-DL_IMPORT(PyThreadState *) PyThreadState_New(PyInterpreterState *);
+DL_IMPORT(PyThreadState *) PyThreadState_New(PyInterpreterState *,
int);
 DL_IMPORT(void) PyThreadState_Clear(PyThreadState *);
 DL_IMPORT(void) PyThreadState_Delete(PyThreadState *);
 #ifdef WITH_THREAD
diff -r -u Python-2.2.2/Include/pythread.h
Python-2.2.2moremod/Include/pythread.h
--- Python-2.2.2/Include/pythread.h	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Include/pythread.h	2003-02-19 17:46:15.000000000
-0500
@@ -8,10 +8,15 @@
 typedef void *PyThread_type_lock;
 typedef void *PyThread_type_sema;
 
+struct bootargs {
+  struct bootstate *boot_raw;
+  long id;
+};
+
 #ifdef __cplusplus
 extern "C" {
 #endif
-
+DL_IMPORT(long) PyThread_get_id(void);
 DL_IMPORT(void) PyThread_init_thread(void);
 DL_IMPORT(long) PyThread_start_new_thread(void (*)(void *), void *);
 DL_IMPORT(void) PyThread_exit_thread(void);
diff -r -u Python-2.2.2/Modules/posixmodule.c
Python-2.2.2moremod/Modules/posixmodule.c
--- Python-2.2.2/Modules/posixmodule.c	2003-02-19 18:52:17.000000000
-0500
+++ Python-2.2.2moremod/Modules/posixmodule.c	2003-02-19
15:53:18.000000000 -0500
@@ -3037,7 +3037,7 @@
 		 	       "when closing popen object");
 		 return -1;  /* unreachable */
 	}
-	pThreadState = PyThreadState_New(pInterpreterState);
+	pThreadState = PyThreadState_New(pInterpreterState, 0);
 	if (!pThreadState) {
 		 Py_FatalError("unable to allocate thread state "
 		 	       "when closing popen object");
diff -r -u Python-2.2.2/Modules/threadmodule.c
Python-2.2.2moremod/Modules/threadmodule.c
--- Python-2.2.2/Modules/threadmodule.c	2003-02-19 18:52:17.000000000
-0500
+++ Python-2.2.2moremod/Modules/threadmodule.c	2003-02-19
18:35:44.000000000 -0500
@@ -171,6 +171,9 @@
 
 /* Module functions */
 
+
+
+
 struct bootstate {
 	PyInterpreterState *interp;
 	PyObject *func;
@@ -178,21 +181,28 @@
 	PyObject *keyw;
 };
 
+//struct bootargs {
+//struct bootstate *boot_raw;
+//long id;
+//};
+
 static void
-t_bootstrap(void *boot_raw)
+t_bootstrap(void *boot_args)
 {
-	struct bootstate *boot = (struct bootstate *) boot_raw;
+        struct bootargs *bargs = (struct bootargs *) boot_args;
+	struct bootstate *boot =  bargs->boot_raw;
 	PyThreadState *tstate;
 	PyObject *res;
 
-	tstate = PyThreadState_New(boot->interp);
+	tstate = PyThreadState_New(boot->interp, bargs->id);
 	PyEval_AcquireThread(tstate);
 	res = PyEval_CallObjectWithKeywords(
 		boot->func, boot->args, boot->keyw);
 	Py_DECREF(boot->func);
 	Py_DECREF(boot->args);
 	Py_XDECREF(boot->keyw);
-	PyMem_DEL(boot_raw);
+	PyMem_DEL(bargs->boot_raw);
+	PyMem_DEL(boot_args);
 	if (res == NULL) {
 		if (PyErr_ExceptionMatches(PyExc_SystemExit))
 			PyErr_Clear();
@@ -213,6 +223,7 @@
 {
 	PyObject *func, *args, *keyw = NULL;
 	struct bootstate *boot;
+	struct bootargs *bargs;
 	long ident;
 
 	if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args,
&keyw))
@@ -232,9 +243,15 @@
 				"optional 3rd arg must be a dictionary");
 		return NULL;
 	}
+
+	bargs = PyMem_NEW(struct bootargs, 1);
+	if (bargs == NULL)
+	        return PyErr_NoMemory();
 	boot = PyMem_NEW(struct bootstate, 1);
 	if (boot == NULL)
 		return PyErr_NoMemory();
+        bargs->boot_raw = boot;
+        bargs->id = PyEval_GetTid();
 	boot->interp = PyThreadState_Get()->interp;
 	boot->func = func;
 	boot->args = args;
@@ -243,7 +260,7 @@
 	Py_INCREF(args);
 	Py_XINCREF(keyw);
 	PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
-	ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
+	ident = PyThread_start_new_thread(t_bootstrap, (void*) bargs);
 	if (ident == -1) {
 		PyErr_SetString(ThreadError, "can't start new thread\n");
 		Py_DECREF(func);
@@ -252,6 +269,7 @@
 		PyMem_DEL(boot);
 		return NULL;
 	}
+
 	return PyInt_FromLong(ident);
 }
 
@@ -282,6 +300,23 @@
 This is synonymous to ``raise SystemExit''.  It will cause the
current\n\
 thread to exit silently unless the exception is caught.";
 
+static PyObject *
+thread_kill_thread(PyObject *self, PyObject *args)
+{
+  int tid;
+  
+  if ( !PyArg_Parse(args, "(i)", &tid) )
+    return NULL;
+  if( PyEval_AddTid( tid ) == -1 )
+    return PyErr_NoMemory();
+  return PyInt_FromLong(0);
+}
+
+static char kill_thread_doc[] =
+"kill_thread(id)\n\
+\n\
+Request that the thread with the given id will ``raise SystemExit``
ASAP.";
+
 #ifndef NO_EXIT_PROG
 static PyObject *
 thread_PyThread_exit_prog(PyObject *self, PyObject *args)
@@ -314,7 +349,8 @@
 	long ident;
 	if (!PyArg_NoArgs(args))
 		return NULL;
-	ident = PyThread_get_thread_ident();
+	ident = PyEval_get_thread_ident();
+	//	ident = PyThread_get_thread_ident();
 	if (ident == -1) {
 		PyErr_SetString(ThreadError, "no current thread ident");
 		return NULL;
@@ -350,6 +386,8 @@
 	 METH_OLDARGS, exit_doc},
 	{"get_ident",		(PyCFunction)thread_get_ident, 
 	 METH_OLDARGS, get_ident_doc},
+	{"kill_thread",		(PyCFunction)thread_kill_thread, 
+	 METH_VARARGS, kill_thread_doc},	
 #ifndef NO_EXIT_PROG
 	{"exit_prog",		(PyCFunction)thread_PyThread_exit_prog},
 #endif
diff -r -u Python-2.2.2/Python/ceval.c
Python-2.2.2moremod/Python/ceval.c
--- Python-2.2.2/Python/ceval.c	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Python/ceval.c	2003-02-19 18:47:57.000000000
-0500
@@ -13,6 +13,7 @@
 #include "eval.h"
 #include "opcode.h"
 #include "structmember.h"
+#include <stdlib.h>
 
 #ifdef macintosh
 #include "macglue.h"
@@ -29,6 +30,12 @@
 #define CHECKEXC 1	/* Double-check exception checking */
 #endif
 
+
+#ifdef WITH_THREAD
+#define NUMTIDSLOTS 20
+#endif
+
+
 typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
 
 /* Forward declarations */
@@ -85,6 +92,8 @@
 #endif
 #endif
 
+
+
 staticforward PyTypeObject gentype;
 
 typedef struct {
@@ -97,6 +106,86 @@
 	int gi_running;
 } genobject;
 
+
+#ifdef WITH_THREAD
+
+struct tidnode tidtable[NUMTIDSLOTS];
+
+int 
+PyEval_AddTid( long tid )
+{
+  struct tidnode *node;
+  struct tidnode *tidchain;
+
+  if(tid <= 0 )
+    return 0;
+  
+  node = PyMem_NEW(struct tidnode, 1);
+  if (node == NULL)
+    return -1;
+  node->tid = tid;
+  
+
+  tidchain = &(tidtable[tid % NUMTIDSLOTS]);
+  node->prev = tidchain->prev;
+  node->next = tidchain;
+  tidchain->prev->next = node;
+  tidchain->prev = node;
+  
+  return 0;
+}
+
+struct tidnode *
+PyEval_GetTidNode( long tid )
+{
+  struct tidnode * node;
+  struct tidnode * tidanchor;
+
+  if(tid <= 0)
+    return NULL; 
+
+  tidanchor = &(tidtable[tid % NUMTIDSLOTS]);
+  for(node = tidanchor->next; node != tidanchor; node = node->next)
+    {
+      if( tid == node->tid )
+	{
+	  return node;
+	}
+      
+    }
+  
+  return NULL;
+}
+
+void 
+PyEval_RemoveTidNode( struct tidnode * node )
+{
+  
+  if( node != NULL )
+    {
+      node->prev->next = node->next;
+      node->next->prev = node->prev;
+      PyMem_DEL(node);      
+    }
+   
+}
+
+void 
+initTidTable( struct tidnode *table, long length )
+{
+  long x;
+  
+  for(x = 0; x < length; x++ )
+    {
+      table[x].prev = &(table[x]);
+      table[x].next = &(table[x]);
+    }
+}
+
+
+#endif //WITH_THREAD
+
+
 static PyObject *
 gen_new(PyFrameObject *f)
 {
@@ -247,6 +336,28 @@
 
 static PyThread_type_lock interpreter_lock = 0;
 static long main_thread = 0;
+static long thread_tid = 1;
+
+long PyEval_get_thread_ident(void)
+{
+  PyThreadState *tstate = PyThreadState_GET();
+  return tstate->id;
+}
+void
+PyEval_IncrementTid(void)
+{
+  thread_tid++;
+  if(thread_tid <= 0)
+    thread_tid = 1;
+}
+
+int
+PyEval_GetTid(void)
+{
+  
+  return thread_tid;
+}
+
 
 void
 PyEval_InitThreads(void)
@@ -257,6 +368,8 @@
 	interpreter_lock = PyThread_allocate_lock();
 	PyThread_acquire_lock(interpreter_lock, 1);
 	main_thread = PyThread_get_thread_ident();
+	initTidTable( tidtable, NUMTIDSLOTS );
+	
 }
 
 void
@@ -512,6 +625,7 @@
 	PyThreadState *tstate = PyThreadState_GET();
 	PyCodeObject *co;
 	unsigned char *first_instr;
+	struct tidnode  *killthread = NULL;
 #ifdef LLTRACE
 	int lltrace;
 #endif
@@ -675,25 +789,43 @@
 			}
 #endif
 
+
+
 #ifdef WITH_THREAD
-			if (interpreter_lock) {
-				/* Give another thread a chance */
+		       
 
-				if (PyThreadState_Swap(NULL) != tstate)
-					Py_FatalError("ceval: tstate mix-up");
-				PyThread_release_lock(interpreter_lock);
+			
 
-				/* Other threads may run now */
+			
 
-				PyThread_acquire_lock(interpreter_lock, 1);
-				if (PyThreadState_Swap(tstate) != NULL)
-					Py_FatalError("ceval: orphan tstate");
+			if (interpreter_lock) {
+			  /* try to find any thread that needs to be killed */
+			  if( (killthread = PyEval_GetTidNode( tstate->id )) 
+			      != NULL)
+			    {
+			      PyEval_RemoveTidNode( killthread );
+			      killthread = NULL;
+			      why = WHY_EXCEPTION;
+			      PyErr_SetObject(PyExc_SystemExit, NULL);
+			      goto on_error;
+			    }
+			  /* Give another thread a chance */
+			  
+			  if (PyThreadState_Swap(NULL) != tstate)
+			    Py_FatalError("ceval: tstate mix-up");
+			  PyThread_release_lock(interpreter_lock);
+			  
+			  /* Other threads may run now */
+			  
+			  PyThread_acquire_lock(interpreter_lock, 1);
+			  if (PyThreadState_Swap(tstate) != NULL)
+			    Py_FatalError("ceval: orphan tstate");
 			}
 #endif
 		}
-
+		
 		/* Extract opcode and argument */
-
+		
 #if defined(Py_DEBUG) || defined(LLTRACE)
 		f->f_lasti = INSTR_OFFSET();
 #endif
diff -r -u Python-2.2.2/Python/pystate.c
Python-2.2.2moremod/Python/pystate.c
--- Python-2.2.2/Python/pystate.c	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Python/pystate.c	2003-02-19 16:00:54.000000000
-0500
@@ -57,7 +57,7 @@
 		interp->dlopenflags = RTLD_LAZY;
 #endif
 #endif
-
+		
 		HEAD_LOCK();
 		interp->next = interp_head;
 		interp_head = interp;
@@ -123,7 +123,7 @@
 }
 
 PyThreadState *
-PyThreadState_New(PyInterpreterState *interp)
+PyThreadState_New(PyInterpreterState *interp, int id)
 {
 	PyThreadState *tstate = PyMem_NEW(PyThreadState, 1);
 	if (_PyThreadState_GetFrame == NULL)
@@ -153,7 +153,7 @@
 		tstate->c_tracefunc = NULL;
 		tstate->c_profileobj = NULL;
 		tstate->c_traceobj = NULL;
-
+		tstate->id = id;
 		HEAD_LOCK();
 		tstate->next = interp->tstate_head;
 		interp->tstate_head = tstate;
diff -r -u Python-2.2.2/Python/pythonrun.c
Python-2.2.2moremod/Python/pythonrun.c
--- Python-2.2.2/Python/pythonrun.c	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Python/pythonrun.c	2003-02-19 15:55:14.000000000
-0500
@@ -122,7 +122,7 @@
 	if (interp == NULL)
 		Py_FatalError("Py_Initialize: can't make first interpreter");
 
-	tstate = PyThreadState_New(interp);
+	tstate = PyThreadState_New(interp, -1);
 	if (tstate == NULL)
 		Py_FatalError("Py_Initialize: can't make first thread");
 	(void) PyThreadState_Swap(tstate);
@@ -310,7 +310,7 @@
 	if (interp == NULL)
 		return NULL;
 
-	tstate = PyThreadState_New(interp);
+	tstate = PyThreadState_New(interp, -1);
 	if (tstate == NULL) {
 		PyInterpreterState_Delete(interp);
 		return NULL;
diff -r -u Python-2.2.2/Python/thread_beos.h
Python-2.2.2moremod/Python/thread_beos.h
--- Python-2.2.2/Python/thread_beos.h	2003-02-19 18:52:17.000000000
-0500
+++ Python-2.2.2moremod/Python/thread_beos.h	2003-02-19
17:24:42.000000000 -0500
@@ -114,11 +114,13 @@
 
 long PyThread_start_new_thread( void (*func)(void *), void *arg )
 {
+        struct bootargs *bargs = (struct bootargs *) arg; 
 	status_t success = 0;
 	thread_id tid;
 	char name[B_OS_NAME_LENGTH];
 	int32 this_thread;
 
+
 	dprintf(("PyThread_start_new_thread called\n"));
 
 	/* We are so very thread-safe... */
@@ -132,7 +134,9 @@
 		success = resume_thread( tid );
 	}
 
-	return ( success == B_NO_ERROR ? tid : -1 );
+	
+
+	return ( success == B_NO_ERROR ? bargs->id : -1 );
 }
 
 long PyThread_get_thread_ident( void )
diff -r -u Python-2.2.2/Python/thread_cthread.h
Python-2.2.2moremod/Python/thread_cthread.h
--- Python-2.2.2/Python/thread_cthread.h	2003-02-19 18:52:17.000000000
-0500
+++ Python-2.2.2moremod/Python/thread_cthread.h	2003-02-19
17:25:46.000000000 -0500
@@ -17,6 +17,7 @@
 long
 PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
+        struct bootargs *bargs = (struct bootargs *) arg; 
 	int success = 0;	/* init not needed when SOLARIS_THREADS and */
 				/* C_THREADS implemented properly */
 
@@ -27,7 +28,7 @@
 	 * so well do it here
 	 */
 	cthread_detach(cthread_fork((cthread_fn_t) func, arg));
-	return success < 0 ? -1 : 0;
+	return success < 0 ? -1 : bargs->id;
 }
 
 long
diff -r -u Python-2.2.2/Python/thread_foobar.h
Python-2.2.2moremod/Python/thread_foobar.h
--- Python-2.2.2/Python/thread_foobar.h	2003-02-19 18:52:17.000000000
-0500
+++ Python-2.2.2moremod/Python/thread_foobar.h	2003-02-19
17:42:37.000000000 -0500
@@ -13,13 +13,21 @@
 long
 PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
+        struct bootargs *bargs = (struct bootargs *) arg; 
 	int success = 0;	/* init not needed when SOLARIS_THREADS and */
 				/* C_THREADS implemented properly */
 
 	dprintf(("PyThread_start_new_thread called\n"));
 	if (!initialized)
 		PyThread_init_thread();
-	return success < 0 ? -1 : 0;
+	if(success >=0 )
+	  {
+	    PyEval_IncrementTid();
+	    return bargs->id;
+	  }
+	else
+	  return -1;
+	//return success < 0 ? -1 : bargs->id;
 }
 
 long
diff -r -u Python-2.2.2/Python/thread_lwp.h
Python-2.2.2moremod/Python/thread_lwp.h
--- Python-2.2.2/Python/thread_lwp.h	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Python/thread_lwp.h	2003-02-19
17:41:53.000000000 -0500
@@ -28,13 +28,22 @@
 
 long PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
+        struct bootargs *bargs = (struct bootargs *) arg; 
 	thread_t tid;
 	int success;
 	dprintf(("PyThread_start_new_thread called\n"));
 	if (!initialized)
 		PyThread_init_thread();
 	success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg);
-	return success < 0 ? -1 : 0;
+	if(success >= 0 )
+	  {
+	    PyEval_IncrementTid();
+	    return bargs->id;
+	  }
+	else
+	  return -1;
+
+	//	return success < 0 ? -1 : bargs->id;
 }
 
 long PyThread_get_thread_ident(void)
diff -r -u Python-2.2.2/Python/thread_nt.h
Python-2.2.2moremod/Python/thread_nt.h
--- Python-2.2.2/Python/thread_nt.h	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Python/thread_nt.h	2003-02-19 17:47:17.000000000
-0500
@@ -169,10 +169,11 @@
 
 long PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
+        struct bootargs *bargs = (struct bootargs *) arg; 
 	unsigned long rv;
 	int success = 0;
 	callobj *obj;
-	int id;
+	long id;
 
 	dprintf(("%ld: PyThread_start_new_thread called\n",
PyThread_get_thread_ident()));
 	if (!initialized)
@@ -193,8 +194,15 @@
 	/* wait for thread to initialize and retrieve id */
 	WaitForSingleObject(obj->done, 5000);  /* maybe INFINITE instead of
5000? */
 	CloseHandle((HANDLE)obj->done);
-	id = obj->id;
+	//id = obj->id;
 	free(obj);
+        if(success)
+	  {
+	    PyEval_IncrementTid();
+	    id = bargs->id;
+	  }
+        else
+          id = -1;
 	return id;
 }
 
diff -r -u Python-2.2.2/Python/thread_os2.h
Python-2.2.2moremod/Python/thread_os2.h
--- Python-2.2.2/Python/thread_os2.h	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Python/thread_os2.h	2003-02-19
17:47:01.000000000 -0500
@@ -24,8 +24,9 @@
 long
 PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
+  struct bootargs *bargs = (struct bootargs *) arg; 
   int aThread;
-  int success = 0;
+  long success = 0;
 
   aThread = _beginthread(func,NULL,65536,arg);
 
@@ -35,6 +36,12 @@
     dprintf(("_beginthread failed. return %ld\n", errno));
   }
 
+  if(success == 0)
+    {
+      success = bargs->id;
+      PyEval_IncrementTid();
+    }
+
   return success;
 }
 
diff -r -u Python-2.2.2/Python/thread_pth.h
Python-2.2.2moremod/Python/thread_pth.h
--- Python-2.2.2/Python/thread_pth.h	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Python/thread_pth.h	2003-02-19
17:48:14.000000000 -0500
@@ -46,6 +46,7 @@
 
 long PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
+        struct bootargs *bargs = (struct bootargs *) arg; 
 	pth_t th;
 	dprintf(("PyThread_start_new_thread called\n"));
 	if (!initialized)
@@ -55,8 +56,15 @@
 				 (void* (*)(void *))func,
 				 (void *)arg
 				 );
+        if(th >= 0 )
+	  {
 
-	return th;
+	    PyEval_IncrementTid();
+	    return bargs->id;
+	  }
+	else
+	  return -1;
+	//	return th;
 }
 
 long PyThread_get_thread_ident(void)
diff -r -u Python-2.2.2/Python/thread_pthread.h
Python-2.2.2moremod/Python/thread_pthread.h
--- Python-2.2.2/Python/thread_pthread.h	2003-02-19 18:52:17.000000000
-0500
+++ Python-2.2.2moremod/Python/thread_pthread.h	2003-02-19
17:38:33.000000000 -0500
@@ -152,6 +152,7 @@
 long
 PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
+        struct bootargs *bargs = (struct bootargs *) arg; 
 	pthread_t th;
 	int success;
  	sigset_t oldmask, newmask;
@@ -215,12 +216,11 @@
 #elif defined(PY_PTHREAD_STD)
 		pthread_detach(th);
 #endif
+		PyEval_IncrementTid();
+		return bargs->id;
 	}
-#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
-	return (long) th;
-#else
-	return (long) *(long *) &th;
-#endif
+	
+	return -1;
 }
 
 /* XXX This implementation is considered (to quote Tim Peters)
"inherently
@@ -294,6 +294,13 @@
 }
 #endif /* NO_EXIT_PROG */
 
+long 
+PyThread_get_id(void)
+{
+  return (long) getpid();
+  
+}
+
 /*
  * Lock support.
  */
diff -r -u Python-2.2.2/Python/thread_sgi.h
Python-2.2.2moremod/Python/thread_sgi.h
--- Python-2.2.2/Python/thread_sgi.h	2003-02-19 18:52:17.000000000 -0500
+++ Python-2.2.2moremod/Python/thread_sgi.h	2003-02-19
17:40:05.000000000 -0500
@@ -174,6 +174,7 @@
 	long addr, size;
 	static int local_initialized = 0;
 #endif /* USE_DL */
+        struct bootargs *bargs = (struct bootargs *) arg; 
 	int success = 0;	/* init not needed when SOLARIS_THREADS and */
 				/* C_THREADS implemented properly */
 
@@ -219,10 +220,14 @@
 			pidlist[maxpidindex++].child = success;
 			dprintf(("pidlist[%d] = %d\n",
 				 maxpidindex-1, success));
+			success = bargs->id;
+			PyEval_IncrementTid();
 		}
 	}
 	if (usunsetlock(count_lock) < 0)
 		perror("usunsetlock (count_lock)");
+
+
 	return success;
 }
 
diff -r -u Python-2.2.2/Python/thread_solaris.h
Python-2.2.2moremod/Python/thread_solaris.h
--- Python-2.2.2/Python/thread_solaris.h	2003-02-19 18:52:17.000000000
-0500
+++ Python-2.2.2moremod/Python/thread_solaris.h	2003-02-19
17:46:51.000000000 -0500
@@ -38,9 +38,10 @@
 long
 PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
+        struct bootargs *bargs = (struct bootargs *) arg; 
 	thread_t tid;
 	struct func_arg *funcarg;
-	int success = 0;	/* init not needed when SOLARIS_THREADS and */
+	long success = 0;	/* init not needed when SOLARIS_THREADS and */
 				/* C_THREADS implemented properly */
 
 	dprintf(("PyThread_start_new_thread called\n"));
@@ -55,7 +56,14 @@
 		free((void *) funcarg);
 		success = -1;
 	}
-	return tid;
+        else
+	  {
+	    success = bargs->id;
+	    PyEval_IncrementTid();
+	  }
+	    //return tid;
+	
+	return success;
 }
 
 long







More information about the Python-list mailing list