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

Kristján Valur Jónsson kristjan at ccpgames.com
Tue Feb 24 02:53:29 CET 2009


Killing a tasklet involves sending it the TaskletExit exception.  The NULL is indication that an exception has been raised.  This will generally cause everyting to unwind up to the top and the tasklet to die.

Offhand, I cannot remember if killing yourself is supposed to work.  But to get the same effect, just raise a TaskletExit exception.
K

-----Original Message-----
From: stackless-bounces at stackless.com [mailto:stackless-bounces at stackless.com] On Behalf Of Chris Jacobson
Sent: 23. febrúar 2009 17:24
To: stackless at stackless.com
Subject: [Stackless] Killing a tasklet waiting on PyChannel_Receive in C module fails

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;
}

_______________________________________________
Stackless mailing list
Stackless at stackless.com
http://www.stackless.com/mailman/listinfo/stackless





More information about the Stackless mailing list