[Stackless] Stackless crash and running on another thread (patches included)

Jeff Senn senn at maya.com
Fri Jun 23 16:14:56 CEST 2006

In some attempts to explore the question I posted the
other day about why calling stackless.run() is restricted
to the main thread; I've come up with this very small
example that crashes python (recursive stack overflow):

import stackless,thread,time
def tsk(a):
def foo():
     y = stackless.tasklet(tsk)(0)

This seems to happen because, during the thread state cleanup when
the main tasklet is "killed", impl_tasklet_kill winds up calling
the "clear" method from the tasklet class which calls kill again
(etc etc).

This does *not* happen during the "main" thread cleanup (I think)
because the type objects themselves have started to finalize and
the tp_clear in the tasklet type has been replaced with "subtype_clear"
rather than the (more specific) "tasklet_clear".

I suspect that this patch is the thing to do; it prevents the
recursion (and may be what was intended in the first place; does
anyone (Christian?) have time to take a second look?)

Index: Stackless/module/taskletobject.c
--- Stackless/module/taskletobject.c    (revision 47071)
+++ Stackless/module/taskletobject.c    (working copy)
@@ -103,7 +103,7 @@
                 Py_XDECREF(_hold); \

-       if (t->f.frame != NULL)
+       if (slp_get_frame(t) != NULL)
                 kill_finally((PyObject *) t);
         TASKLET_SETVAL(t, Py_None); /* always non-zero */
         /* unlink task from cstate */

With this patch made (which prevents the above crash), I can't generate 
any cases where stackless.run() on a non-main thread causes any 
additional problems (Note: that doesn't mean that I *completely* 
understand that it is safe either).

So I also suggest this patch (to allow .run() in another thread).

Index: Stackless/module/stacklessmodule.c
--- Stackless/module/stacklessmodule.c  (revision 47083)
+++ Stackless/module/stacklessmodule.c  (working copy)
@@ -216,7 +216,7 @@
         int err;

         if (ts->st.main == NULL) return PyStackless_RunWatchdog_M(timeout);
-       if (ts != slp_initial_tstate || ts->st.current != ts->st.main)
+       if (ts->st.current != ts->st.main)
                     "run() must be run from the main thread's main 

Stackless mailing list
Stackless at stackless.com

More information about the Stackless mailing list