[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