[pypy-svn] r22717 - pypy/dist/pypy/module/stackless

tismer at codespeak.net tismer at codespeak.net
Fri Jan 27 10:52:16 CET 2006


Author: tismer
Date: Fri Jan 27 10:52:15 2006
New Revision: 22717

Modified:
   pypy/dist/pypy/module/stackless/interp_coroutine.py
Log:
small refinements, exceptions, more to come...

Modified: pypy/dist/pypy/module/stackless/interp_coroutine.py
==============================================================================
--- pypy/dist/pypy/module/stackless/interp_coroutine.py	(original)
+++ pypy/dist/pypy/module/stackless/interp_coroutine.py	Fri Jan 27 10:52:15 2006
@@ -56,12 +56,15 @@
             # redirect all unhandled exceptions to the parent
             costate.things_to_do = True
             costate.temp_exc = e
-        if self.parent.frame is None:
-            self.parent = costate.main
+        while self.parent.frame is None:
+            # greenlet behavior is fine
+            self.parent = self.parent.parent
         return self._update_state(self.parent)
 
     def switch(self):
         if self.frame is None:
+            # considered a programming error.
+            # greenlets and tasklets have different ideas about this.
             raise CoroutineDamage
         costate.last.frame = self._update_state(self).switch()
         # note that last gets updated before assignment!
@@ -75,7 +78,6 @@
     _update_state = staticmethod(_update_state)
 
     def kill(self):
-        self._userdel()
         if costate.current is self:
             raise CoroutineExit
         costate.things_to_do = True
@@ -83,6 +85,10 @@
         self.parent = costate.current
         self.switch()
 
+    def _kill_finally(self):
+        self._userdel()
+        self.kill()
+
     def __del__(self):
         # provide the necessary clean-up if this coro is left
         # with a frame.
@@ -121,7 +127,7 @@
         obj.parent = costate.current
         if obj is costate.del_last:
             costate.del_first = costate.del_last = None
-        obj.kill()
+        obj._kill_finally()
     else:
         costate.things_to_do = False
 
@@ -152,12 +158,21 @@
         return space.wrap(co)
 
     def w_bind(self, w_func, __args__):
+        if self.frame is not None:
+            raise OperationError(space.w_ValueError, space.wrap(
+                "cannot bind a bound Coroutine"))
         thunk = _AppThunk(self.space, w_func, __args__)
         self.bind(thunk)
 
     def w_switch(self):
+        if self.frame is None:
+            raise OperationError(space.w_ValueError, space.wrap(
+                "cannot switch to an unbound Coroutine"))
         self.switch()
 
+    def w_kill(self):
+        self.kill()
+
     def __del__(self):
         if self.frame is not None or self.space.lookup(self, '__del__') is not None:
             postpone_deletion(self)
@@ -185,5 +200,6 @@
     bind = interp2app(AppCoroutine.w_bind,
                       unwrap_spec=['self', W_Root, Arguments]),
     switch = interp2app(AppCoroutine.w_switch),
+    kill = interp2app(AppCoroutine.w_kill),
     is_zombie = GetSetProperty(AppCoroutine.w_get_is_zombie, doc=AppCoroutine.get_is_zombie.__doc__),
 )



More information about the Pypy-commit mailing list