[pypy-svn] r64205 - in pypy/trunk/pypy: lib/app_test rlib

cfbolz at codespeak.net cfbolz at codespeak.net
Fri Apr 17 00:44:44 CEST 2009


Author: cfbolz
Date: Fri Apr 17 00:44:43 2009
New Revision: 64205

Modified:
   pypy/trunk/pypy/lib/app_test/test_coroutine.py
   pypy/trunk/pypy/rlib/rcoroutine.py
Log:
(cfbolz, pedronis): fix the problem in coroutine cleanup: you need to always
enqueue a coroutine for deletion, even if it does not have a frame because the
userdel needs to be called.


Modified: pypy/trunk/pypy/lib/app_test/test_coroutine.py
==============================================================================
--- pypy/trunk/pypy/lib/app_test/test_coroutine.py	(original)
+++ pypy/trunk/pypy/lib/app_test/test_coroutine.py	Fri Apr 17 00:44:43 2009
@@ -18,7 +18,7 @@
         co.switch()
         assert not co.is_zombie
 
-    def test_is_zombie_del(self):
+    def test_is_zombie_del_without_frame(self):
         import gc
         res = []
         class MyCoroutine(coroutine):
@@ -30,12 +30,36 @@
         co.bind(f)
         co.switch()
         del co
-        for i in range(5):
+        for i in range(10):
             gc.collect()
             if res:
                 break
-        if not res:
-            skip("MyCoroutine object not garbage-collected yet?")
+        co = coroutine()
+        co.bind(f)
+        co.switch()
+        assert res[0], "is_zombie was False in __del__"
+
+    def test_is_zombie_del_with_frame(self):
+        import gc
+        res = []
+        class MyCoroutine(coroutine):
+            def __del__(self):
+                res.append(self.is_zombie)
+        main = coroutine.getcurrent()
+        def f():
+            print 'in coro'
+            main.switch()
+        co = MyCoroutine()
+        co.bind(f)
+        co.switch()
+        del co
+        for i in range(10):
+            gc.collect()
+            if res:
+                break
+        co = coroutine()
+        co.bind(f)
+        co.switch()
         assert res[0], "is_zombie was False in __del__"
 
     def test_raise_propagate(self):

Modified: pypy/trunk/pypy/rlib/rcoroutine.py
==============================================================================
--- pypy/trunk/pypy/rlib/rcoroutine.py	(original)
+++ pypy/trunk/pypy/rlib/rcoroutine.py	Fri Apr 17 00:44:43 2009
@@ -282,15 +282,13 @@
         self.kill()
 
     def __del__(self):
-        # provide the necessary clean-up if this coro is left
-        # with a frame.
+        # provide the necessary clean-up
         # note that AppCoroutine has to take care about this
         # as well, including a check for user-supplied __del__.
         # Additionally note that in the context of __del__, we are
         # not in the position to issue a switch.
         # we defer it completely.
-        if self.frame is not None and syncstate is not None:
-            syncstate.postpone_deletion(self)
+        syncstate.postpone_deletion(self)
 
     # coroutines need complete control over their __del__ behaviour. In
     # particular they need to care about calling space.userdel themselves



More information about the Pypy-commit mailing list