From 6f09211e8d2514536ab414890a19482342d37a62 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Sun, 11 Jan 2009 19:39:20 +0600 Subject: [PATCH] deleted greenlib.py --- eventlet/greenlib.py | 335 ------------------------------------------- 1 file changed, 335 deletions(-) delete mode 100644 eventlet/greenlib.py diff --git a/eventlet/greenlib.py b/eventlet/greenlib.py deleted file mode 100644 index e293112..0000000 --- a/eventlet/greenlib.py +++ /dev/null @@ -1,335 +0,0 @@ -"""\ -@file greenlib.py -@author Bob Ippolito - -Copyright (c) 2005-2006, Bob Ippolito -Copyright (c) 2007, Linden Research, Inc. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -""" -import sys -import itertools - -from eventlet.support import greenlet - -from eventlet import tls - -__all__ = [ - 'switch', 'kill', 'tracked_greenlets', - 'greenlet_id', 'greenlet_dict', 'GreenletContext', - 'tracked_greenlet', -] - -try: - reversed -except NameError: - def reversed(something): - for x in something[::-1]: - yield x - -_threadlocal = tls.local() - -def tracked_greenlet(): - """ - Returns a greenlet that has a greenlet-local dictionary and can be - used with GreenletContext and enumerated with tracked_greenlets - """ - return greenlet.greenlet(greenlet_body) - -class GreenletContextManager(object): - """ - Per-thread manager for GreenletContext. Created lazily on registration - """ - def __new__(cls, *args, **kw): - dct = greenlet_dict() - self = dct.get('greenlet_context', None) - if self is not None: - return self - self = super(GreenletContextManager, cls).__new__(cls, *args, **kw) - dct['greenlet_context'] = self - self.contexts = [] - return self - - def add_context(self, ctx): - fn = getattr(ctx, '_swap_in', None) - if fn is not None: - fn() - self.contexts.append(ctx) - - def remove_context(self, ctx): - try: - idx = self.contexts.index(ctx) - except ValueError: - return - else: - del self.contexts[idx] - fn = getattr(ctx, '_swap_out', None) - if fn is not None: - fn() - fn = getattr(ctx, '_finalize', None) - if fn is not None: - fn() - - def swap_in(self): - for ctx in self.contexts: - fn = getattr(ctx, '_swap_in', None) - if fn is not None: - fn() - - def swap_out(self): - for ctx in reversed(self.contexts): - fn = getattr(ctx, '_swap_out', None) - if fn is not None: - fn() - - def finalize(self): - for ctx in reversed(self.contexts): - fn = getattr(ctx, '_swap_out', None) - if fn is not None: - fn() - fn = getattr(ctx, '_finalize', None) - if fn is not None: - fn() - del self.contexts[:] - try: - del greenlet_dict()['greenlet_context'] - except KeyError: - pass - -class GreenletContext(object): - """ - A context manager to be triggered when a specific tracked greenlet is - swapped in, swapped out, or finalized. - - To use, subclass and override the swap_in, swap_out, and/or finalize - methods, for example:: - - import greenlib - from greenlib import greenlet_id, tracked_greenlet, switch - - class NotifyContext(greenlib.GreenletContext): - - def swap_in(self): - print "swap_in" - - def swap_out(self): - print "swap_out" - - def finalize(self): - print "finalize" - - def another_greenlet(): - print "another_greenlet" - - def notify_demo(): - print "starting" - NotifyContext().register() - switch(tracked_greenlet(), (another_greenlet,)) - print "finishing" - # we could have kept the NotifyContext object - # to unregister it here but finalization of all - # contexts is implicit when the greenlet returns - - t = tracked_greenlet() - switch(t, (notify_demo,)) - - The output should be: - - starting - swap_in - swap_out - another_greenlet - swap_in - finishing - swap_out - finalize - - """ - _balance = 0 - - def _swap_in(self): - if self._balance != 0: - raise RuntimeError("balance != 0: %r" % (self._balance,)) - self._balance = self._balance + 1 - fn = getattr(self, 'swap_in', None) - if fn is not None: - fn() - - def _swap_out(self): - if self._balance != 1: - raise RuntimeError("balance != 1: %r" % (self._balance,)) - self._balance = self._balance - 1 - fn = getattr(self, 'swap_out', None) - if fn is not None: - fn() - - def register(self): - GreenletContextManager().add_context(self) - - def unregister(self): - GreenletContextManager().remove_context(self) - - def _finalize(self): - fn = getattr(self, 'finalize', None) - if fn is not None: - fn() - - -def kill(g): - """ - Kill the given greenlet if it is alive by sending it a GreenletExit. - - Note that of any other exception is raised, it will pass-through! - """ - if not g: - return - kill_exc = greenlet.GreenletExit() - try: - try: - g.parent = greenlet.getcurrent() - except ValueError: - pass - try: - switch(g, exc=kill_exc) - except SwitchingToDeadGreenlet: - pass - except greenlet.GreenletExit, e: - if e is not kill_exc: - raise - -def tracked_greenlets(): - """ - Return a list of greenlets tracked in this thread. Tracked greenlets - use greenlet_body() to ensure that they have greenlet-local storage. - """ - try: - return _threadlocal.greenlets.keys() - except AttributeError: - return [] - -def greenlet_id(self=None): - """ - Get the id of the current tracked greenlet, returns None if the - greenlet is not tracked. - """ - try: - d = greenlet_dict(self) - except RuntimeError: - return None - return d['greenlet_id'] - -def greenlet_dict(self=None): - """ - Return the greenlet local storage for this greenlet. Raises RuntimeError - if this greenlet is not tracked. - """ - if self is None: - self = greenlet.getcurrent() - try: - return _threadlocal.greenlets[self] - except (AttributeError, KeyError): - raise RuntimeError("greenlet %r is not tracked" % (self,)) - -def _greenlet_context(dct=None): - if dct is None: - try: - dct = greenlet_dict() - except RuntimeError: - return None - return dct.get('greenlet_context', None) - -def _greenlet_context_call(name, dct=None): - ctx = _greenlet_context(dct) - fn = getattr(ctx, name, None) - if fn is not None: - fn() - -def greenlet_body(value, exc): - """ - Track the current greenlet during the execution of the given callback, - normally you would use tracked_greenlet() to get a greenlet that uses this. - - Greenlets using this body must be greenlib.switch()'ed to - """ - from eventlet import api - if exc is not None: - if isinstance(exc, tuple): - raise exc[0], exc[1], exc[2] - raise exc - cb, args = value[0], value[1:] - try: - greenlets = _threadlocal.greenlets - except AttributeError: - greenlets = _threadlocal.greenlets = {} - else: - if greenlet.getcurrent() in greenlets: - raise RuntimeError("greenlet_body can not be called recursively!") - try: - greenlet_id = _threadlocal.next_greenlet_id.next() - except AttributeError: - greenlet_id = 1 - _threadlocal.next_greenlet_id = itertools.count(2) - cur = greenlet.getcurrent() - greenlets[cur] = {'greenlet_id': greenlet_id} - try: - return cb(*args) - finally: - _greenlet_context_call('finalize') - greenlets.pop(cur, None) - api.get_hub().cancel_timers(cur, quiet=True) - - -class SwitchingToDeadGreenlet(RuntimeError): - pass - - -def switch(other=None, value=None, exc=None): - """ - Switch to another greenlet, passing value or exception - """ - self = greenlet.getcurrent() - if other is None: - other = self.parent - if other is None: - other = self - if not (other or hasattr(other, 'run')): - raise SwitchingToDeadGreenlet("Switching to dead greenlet %r %r %r" % (other, value, exc)) - _greenlet_context_call('swap_out') - sys.exc_clear() # don't pass along exceptions to the other coroutine - try: - rval = other.switch(value, exc) - if not rval or not other: - res, exc = rval, None - else: - res, exc = rval - except: - res, exc = None, sys.exc_info() - _greenlet_context_call('swap_in') - # *NOTE: we don't restore exc_info, so don't switch inside an - # exception handler and then call sys.exc_info() or use bare - # raise. Instead, explicitly save off the exception before - # switching. We need an extension that allows us to restore the - # exception state at this point because vanilla Python doesn't - # allow that. - if isinstance(exc, tuple): - typ, exc, tb = exc - raise typ, exc, tb - elif exc is not None: - raise exc - - return res