8000 Let channels use the new delayed decref mechanism. This fixes a cras… · stackless-dev/stackless_historic@446a5dd · GitHub
[go: up one dir, main page]

Skip to content

Commit 446a5dd

Browse files
author
kristjan.jonsson
committed
Let channels use the new delayed decref mechanism. This fixes a crash case where a tasklet would block on a temporary channel.
git-svn-id: http://svn.python.org/projects/stackless/trunk@79438 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 9c3b500 commit 446a5dd

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

Stackless/module/channelobject.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,18 @@ generic_channel_action(PyChannelObject *self, PyObject *arg, int dir, int stackl
471471
slp_channel_insert(self, source, dir);
472472
target = ts->st.current;
473473
}
474+
475+
/* Make sure that the channel will exist past the actual switch, if
476+
* we are softswitching. A temporary channel might disappear.
477+
*/
478+
if (self->ob_refcnt==1) {
479+
assert(ts->st.del_post_switch == NULL);
480+
ts->st.del_post_switch = (PyObject*)self;
481+
Py_INCREF(self);
482+
}
474483
ts->st.runflags |= runflags; /* extra info for slp_schedule_task */
475484
retval = slp_schedule_task(source, target, stackless);
485+
476486
if (interthread) {
477487
if (cando) {
478488
Py_DECREF(target);

Stackless/unittests/test_defects.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,33 @@ def func(self, chan):
8888
chan = stackless.channel()
8989
stackless.tasklet(func)(self, chan)
9090
chan.receive()
91+
92+
class Channel(unittest.TestCase):
93+
def testTemporaryChannel(self):
94+
def f1():
95+
stackless.channel().receive()
96+
97+
stackless.tasklet(f1)()
98+
old = stackless.enable_softswitch(True)
99+
try:
100+
stackless.run()
101+
finally:
102+
stackless.enable_softswitch(old)
103+
104+
def testTemporaryChannel2(self):
105+
def f1():
106+
stackless.channel().receive()
107+
def f2():
108+
pass
109+
110+
stackless.tasklet(f1)()
111+
stackless.tasklet(f2)()
112+
old = stackless.enable_softswitch(True)
113+
try:
114+
stackless.run()
115+
finally:
116+
stackless.enable_softswitch(old)
117+
91118

92119
if __name__ == '__main__':
93120
import sys

0 commit comments

Comments
 (0)
0