[Stackless] Killing a tasklet waiting on PyChannel_Receive in C module fails

Chris Jacobson mainecoon at gmail.com
Mon Feb 23 10:24:06 CET 2009


If a tasklet that is currently in a C function waiting on a
PyChannel_Receive is killed from another tasklet, the receiving
tasklet resumes with NULL returned on the Receive, and doesn't die.

Additionally, a tasklet cannot call PyTasklet_Kill on itself; it will
simply reschedule itself.

Maybe I'm doing something wrong, or something that shouldn't/can't be done.


Here's the repro case, using boost::python.  You will need to
uncomment one of the two functions in main().
In the first case, it will repeatedly print "Dying soon.".  In the
second, it will repeatedly print "Dying now."  In both cases, it
should only print once.


#include <boost/python/detail/wrap_python.hpp>
#include <boost/python.hpp>

#include "stackless_api.h"


void KillSelf()
{
	PyTasklet_Kill( reinterpret_cast<PyTaskletObject
*>(PyStackless_GetCurrent()) );
}

void Wait( PyObject *chan )
{
	PyObject *result = PyChannel_Receive(
reinterpret_cast<PyChannelObject *>(chan) );
	Py_XDECREF(result);	// result == NULL
}

BOOST_PYTHON_MODULE(killtest)
{
	py::def("kill", &KillSelf);
	py::def("wait", &Wait);
}


void WaiterWontDie()
{
	PyImport_AppendInittab("killtest", &initkilltest);
	Py_Initialize();

	//	Waiter Won't Die
	PyRun_SimpleString(
		"import killtest, stackless\n"
		"\n"
		"def wontDieFunc(chan):\n"
		"    while (1):\n"
		"        print \"Dying soon...\"\n"
		"        killtest.wait(chan)\n"
		"\n"
		"chan = stackless.channel()\n"
		"task = stackless.tasklet(wontDieFunc)(chan)\n"
		"\n"
		"while (1):\n"
		"    stackless.schedule()\n"
		"    task.kill()\n");
}


void CantKillSelf()
{
	PyImport_AppendInittab("killtest", &initkilltest);
	Py_Initialize();

	//	Self-kill test
	PyRun_SimpleString(
		"import killtest, stackless\n"
		"\n"
		"def taskFunc():\n"
		"    while (1):\n"
		"        print \"Dying now...\"\n"
		"        killtest.kill()\n"
		"\n"
		"task = stackless.tasklet(taskFunc)()\n"
		"task.run()\n"
		"\n"
		"while (1):\n"
		"    stackless.schedule()\n");
}



int main(int argc, char **argv)
{
	//	Uncomment one of the two functions
	//WaiterWontDie();
	//CantKillSelf();
	return 0;
}




More information about the Stackless mailing list