[pypy-svn] r23501 - pypy/dist/pypy/module/stackless
tismer at codespeak.net
tismer at codespeak.net
Sun Feb 19 23:22:37 CET 2006
Author: tismer
Date: Sun Feb 19 23:22:33 2006
New Revision: 23501
Added:
pypy/dist/pypy/module/stackless/coroutine.py (contents, props changed)
Log:
houpps - forgot to add this new file
Added: pypy/dist/pypy/module/stackless/coroutine.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/stackless/coroutine.py Sun Feb 19 23:22:33 2006
@@ -0,0 +1,142 @@
+"""
+Coroutine implementation for application level on top
+of the internal coroutines.
+This is an extensible concept. Multiple implementations
+of concurrency can exist together, if they follow the
+basic concept of maintaining their own costate.
+
+There is also some diversification possible by using
+multiple costates for the same type. This leads to
+disjoint switchable sets within the same type.
+
+I'm not so sure to what extent the opposite is possible, too.
+I.e., merging the costate of tasklets and greenlets would
+allow them to be parents of each other. Needs a bit more
+experience to decide where to set the limits.
+"""
+
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.argument import Arguments
+from pypy.interpreter.typedef import GetSetProperty, TypeDef
+from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w
+from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.function import StaticMethod
+
+from pypy.module.stackless.stackless_flags import StacklessFlags
+from pypy.module.stackless.interp_coroutine import Coroutine, BaseCoState
+
+class _AppThunk(object):
+
+ def __init__(self, space, costate, w_obj, args):
+ self.space = space
+ self.costate = costate
+ if not space.is_true(space.callable(w_obj)):
+ raise OperationError(
+ space.w_TypeError,
+ space.mod(space.wrap('object %r is not callable'),
+ space.newtuple([w_obj])))
+ self.w_func = w_obj
+ self.args = args
+
+ def call(self):
+ self.costate.w_tempval = self.space.call_args(self.w_func, self.args)
+
+
+class AppCoroutine(Coroutine): # XXX, StacklessFlags):
+
+ def __init__(self, space):
+ self.space = space
+ state = self._get_state(space)
+ Coroutine.__init__(self, state)
+ self.flags = 0
+
+ def descr_method__new__(space, w_subtype):
+ co = space.allocate_instance(AppCoroutine, w_subtype)
+ AppCoroutine.__init__(co, space)
+ return space.wrap(co)
+
+ def _get_state(space):
+ return space.fromcache(AppCoState)
+ _get_state = staticmethod(_get_state)
+
+ def w_bind(self, w_func, __args__):
+ space = self.space
+ if self.frame is not None:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "cannot bind a bound Coroutine"))
+ state = self.costate
+ thunk = _AppThunk(space, state, w_func, __args__)
+ self.bind(thunk)
+
+ def w_switch(self):
+ space = self.space
+ if self.frame is None:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "cannot switch to an unbound Coroutine"))
+ state = self.costate
+ self.switch()
+ w_ret, state.w_tempval = state.w_tempval, space.w_None
+ return w_ret
+
+ def w_kill(self):
+ self.kill()
+
+ def _userdel(self):
+ if self.get_is_zombie():
+ return
+ self.set_is_zombie(True)
+ self.space.userdel(self)
+
+ def w_getcurrent(space):
+ return space.wrap(AppCoroutine._get_state(space).current)
+ w_getcurrent = staticmethod(w_getcurrent)
+
+
+# _mixin_ did not work
+for methname in StacklessFlags.__dict__:
+ meth = getattr(StacklessFlags, methname)
+ if hasattr(meth, 'im_func'):
+ setattr(AppCoroutine, meth.__name__, meth.im_func)
+del meth, methname
+
+def w_get_is_zombie(space, self):
+ return space.wrap(self.get_is_zombie())
+AppCoroutine.w_get_is_zombie = w_get_is_zombie
+
+def makeStaticMethod(module, classname, funcname):
+ space = module.space
+ space.appexec(map(space.wrap, (module, classname, funcname)), """
+ (module, klassname, funcname):
+ klass = getattr(module, klassname)
+ func = getattr(klass, funcname)
+ setattr(klass, funcname, staticmethod(func.im_func))
+ """)
+
+def post_install(module):
+ makeStaticMethod(module, 'coroutine', 'getcurrent')
+ space = module.space
+ AppCoroutine._get_state(space).post_install()
+
+# space.appexec("""() :
+
+# maybe use __spacebind__ for postprocessing
+
+AppCoroutine.typedef = TypeDef("coroutine",
+ __new__ = interp2app(AppCoroutine.descr_method__new__.im_func),
+ 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__),
+ getcurrent = interp2app(AppCoroutine.w_getcurrent),
+)
+
+class AppCoState(BaseCoState):
+ def __init__(self, space):
+ BaseCoState.__init__(self)
+ self.w_tempval = space.w_None
+ self.space = space
+
+ def post_install(self):
+ self.current = self.main = self.last = AppCoroutine(self.space)
More information about the Pypy-commit
mailing list