Prompted by Jeff Senn's problems I decided to add a unit test to stackless.
The stackless module already has a test_outside() function which emulates being 
called from outside and does a PyStackless_Schedule() call.

The test is as follows:

#test_outside.py
import unittest
import stackless

class TestOutside(unittest.TestCase):

    def testOutside1(self):
        def null():
            pass
        stackless.tasklet(null)()
        stackless.test_outside()

if __name__ == '__main__':
    import sys
    if not sys.argv[1:]:
        sys.argv.append('-v')

    unittest.main()


Now, running this in debug triggers an assertion.  After much digging, I found 
that it is caused by this code, in PyObject_Call() (which is called by the 
cframe executing the "schedule" call.:
if (Py_EnterRecursiveCall(" while calling a Python object"))
                 return NULL;
             result = (STACKLESS_PROMOTE(func), (*call)(func, arg, kw));
             STACKLESS_ASSERT();
             Py_LeaveRecursiveCall();
The problem is, that once the *call returns, we have softswitched, and so the 
Py_LeaveRecursiveCall() is modifying ts->recursion_level belonging to a 
different tasklet.  In this case the freshly initialized tasklet, and lowering 
it to -1.
As expected, this screws up the recursion level accounting and throws an 
assertion in debug builds.

I am as of yet unsure as to how I should proceed.  It seems as though 
PyObject_Call is incompatible with methods that can perform softswitching.  
Perhaps we could undo the recursion bookkeeping in this case by decrementing 
and incremeting it in  run_cframe (line 225), but it seems like a cludge.  Any 
thoughts?
K
_______________________________________________
Stackless mailing list
Stackless@stackless.com
http://www.stackless.com/mailman/listinfo/stackless

Reply via email to