Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

0 views
Skip to first unread message

anton wilson

unread,
Feb 19, 2003, 7:12:10 PM2/19/03
to
Apply the patch this way:
From inside the Python source folder: Python2.2.2
patch -p1 < patch_name


anton wilson

unread,
Feb 19, 2003, 7:09:06 PM2/19/03
to
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

Aahz

unread,
Feb 24, 2003, 10:38:28 AM2/24/03
to
In article <mailman.104569865...@python.org>,

anton wilson <anton....@camotion.com> wrote:
>
>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.

Sounds interesting. Submit the patch to SourceForge.
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

Register for PyCon now! http://www.python.org/pycon/reg.html

0 new messages