[py-svn] r37642 - py/trunk/py/c-extension/greenlet
arigo at codespeak.net
arigo at codespeak.net
Wed Jan 31 00:07:50 CET 2007
Author: arigo
Date: Wed Jan 31 00:07:48 2007
New Revision: 37642
Modified:
py/trunk/py/c-extension/greenlet/greenlet.c
py/trunk/py/c-extension/greenlet/test_greenlet.py
Log:
issue40 resolved
Thanks ghazel. I fixed this by directly capturing ts_current in a local
variable instead of reloading it. I also reviewed the code a bit and
found another place where ts_current could be used out of date.
Modified: py/trunk/py/c-extension/greenlet/greenlet.c
==============================================================================
--- py/trunk/py/c-extension/greenlet/greenlet.c (original)
+++ py/trunk/py/c-extension/greenlet/greenlet.c Wed Jan 31 00:07:48 2007
@@ -394,7 +394,8 @@
/* in the new greenlet */
PyObject* args;
PyObject* result;
- ts_current->stack_start = (char*) 1; /* running */
+ PyGreenlet* ts_self = ts_current;
+ ts_self->stack_start = (char*) 1; /* running */
args = ts_passaround;
if (args == NULL) /* pending exception */
@@ -407,8 +408,8 @@
Py_DECREF(run);
result = g_handle_exit(result);
/* jump back to parent */
- ts_current->stack_start = NULL; /* dead */
- g_switch(ts_current->parent, result);
+ ts_self->stack_start = NULL; /* dead */
+ g_switch(ts_self->parent, result);
/* must not return from here! */
Py_FatalError("XXX memory exhausted at a very bad moment");
}
@@ -463,6 +464,8 @@
because the 'parent' field chain would hold a
reference */
PyObject* result;
+ if (!STATE_OK)
+ return -1;
Py_INCREF(ts_current);
self->parent = ts_current;
/* Send the greenlet a GreenletExit exception. */
Modified: py/trunk/py/c-extension/greenlet/test_greenlet.py
==============================================================================
--- py/trunk/py/c-extension/greenlet/test_greenlet.py (original)
+++ py/trunk/py/c-extension/greenlet/test_greenlet.py Wed Jan 31 00:07:48 2007
@@ -142,3 +142,17 @@
assert not g
assert next == "meaning of life"
assert g.gr_frame is None
+
+def test_thread_bug():
+ if not thread:
+ py.test.skip("this is a test about thread")
+ import time
+ def runner(x):
+ g = greenlet(lambda: time.sleep(x))
+ g.switch()
+ t1 = threading.Thread(target=runner, args=(0.2,))
+ t2 = threading.Thread(target=runner, args=(0.3,))
+ t1.start()
+ t2.start()
+ t1.join()
+ t2.join()
More information about the py-svn
mailing list