[svn r37642] 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.

--HG--
branch : trunk
This commit is contained in:
arigo 2007-01-31 00:07:48 +01:00
parent e721d85278
commit 6aaca64290
2 changed files with 20 additions and 3 deletions

View File

@ -394,7 +394,8 @@ static void g_initialstub(void* mark)
/* in the new greenlet */ /* in the new greenlet */
PyObject* args; PyObject* args;
PyObject* result; PyObject* result;
ts_current->stack_start = (char*) 1; /* running */ PyGreenlet* ts_self = ts_current;
ts_self->stack_start = (char*) 1; /* running */
args = ts_passaround; args = ts_passaround;
if (args == NULL) /* pending exception */ if (args == NULL) /* pending exception */
@ -407,8 +408,8 @@ static void g_initialstub(void* mark)
Py_DECREF(run); Py_DECREF(run);
result = g_handle_exit(result); result = g_handle_exit(result);
/* jump back to parent */ /* jump back to parent */
ts_current->stack_start = NULL; /* dead */ ts_self->stack_start = NULL; /* dead */
g_switch(ts_current->parent, result); g_switch(ts_self->parent, result);
/* must not return from here! */ /* must not return from here! */
Py_FatalError("XXX memory exhausted at a very bad moment"); Py_FatalError("XXX memory exhausted at a very bad moment");
} }
@ -463,6 +464,8 @@ static int kill_greenlet(PyGreenlet* self)
because the 'parent' field chain would hold a because the 'parent' field chain would hold a
reference */ reference */
PyObject* result; PyObject* result;
if (!STATE_OK)
return -1;
Py_INCREF(ts_current); Py_INCREF(ts_current);
self->parent = ts_current; self->parent = ts_current;
/* Send the greenlet a GreenletExit exception. */ /* Send the greenlet a GreenletExit exception. */

View File

@ -142,3 +142,17 @@ def test_frame():
assert not g assert not g
assert next == "meaning of life" assert next == "meaning of life"
assert g.gr_frame is None 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()