def switch(self, *args, **kwargs): # switch must be called from server greenlet assert get_current_greenlet() is self._sess._server_greenlet try: task = self._g.switch(*args, **kwargs) except SystemExit: self._on_death(True) return except Exception: self._on_death(format_exc(limit=None, chain=False)) return # lua_eval call or simply idle if isinstance(task, bytes): x = self while x._g.dead: x = x._parent self._sess._sender(task[0:1] + ser.serialize(x._task_id) + task[1:]) if self._g.dead: if self._parent is None: self._on_death(True) else: self._on_death()
def __init__(self, computer_id, sender): # computer_id is unique identifier of a CCSession self._computer_id = computer_id self._tid_allocator = map(base36, count(start=1)) self._sender = sender self._greenlets = {} self._server_greenlet = get_current_greenlet() self._program_greenlet = None self._evr = CCEventRouter( lambda event: self._sender(b'S' + ser.serialize(event)), lambda event: self._sender(b'U' + ser.serialize(event)), lambda task_id: self._greenlets[task_id].defer_switch('event'), )
def __init__(self, body_fn, sess=None): if sess is None: self._sess = get_current_session() else: self._sess = sess self._task_id = self._sess.create_task_id() self._sess._greenlets[self._task_id] = self parent_g = get_current_greenlet() if parent_g is self._sess._server_greenlet: self._parent = None else: self._parent = parent_g.cc_greenlet self._parent._children.add(self._task_id) self._children = set() self._g = greenlet(body_fn) self._g.cc_greenlet = self
get_current_greenlet = greenlet.getcurrent del greenlet except: get_current_greenlet = int try: from thread import get_ident as get_current_thread, allocate_lock except ImportError: from dummy_thread import get_ident as get_current_thread, allocate_lock from werkzeug.wsgi import ClosingIterator from werkzeug._internal import _patch_wrapper if get_current_greenlet is int: get_ident = get_current_thread else: get_ident = lambda: (get_current_thread(), get_current_greenlet()) def release_local(local): local.__release_local__() class Local(object): __slots__ = ('__storage__', '__lock__') def __init__(self): object.__setattr__(self, '__storage__', {}) object.__setattr__(self, '__lock__', allocate_lock()) def __iter__(self): return self.__storage__.iteritems()
def get_ident(): return get_current_thread(), get_current_greenlet()
try: from _thread import get_ident as get_current_thread, allocate_lock except ImportError: # pragma: no cover try: from thread import get_ident as get_current_thread, allocate_lock except ImportError: # pragma: no cover from dummy_thread import get_ident as get_current_thread, allocate_lock # get the best ident function. if greenlets are not installed we can # safely just use the builtin thread function and save a python methodcall # and the cost of calculating a hash. if get_current_greenlet is int: # pragma: no cover get_ident = get_current_thread else: get_ident = lambda: (get_current_thread(), get_current_greenlet()) def release_local(local): """Releases the contents of the local for the current context. This makes it possible to use locals without a manager. Example:: >>> loc = Local() >>> loc.foo = 42 >>> release_local(loc) >>> hasattr(loc, 'foo') False With this function one can release :class:`Local` objects as well
def get_current_session(): try: return get_current_greenlet().cc_greenlet._sess except AttributeError: raise RuntimeError('Computercraft function was called outside context')
def _is_global_greenlet(): return not hasattr(get_current_greenlet(), 'cc_greenlet')
def on_task_result(self, task_id, result): assert get_current_greenlet() is self._server_greenlet if task_id not in self._greenlets: # ignore for dropped tasks return self._greenlets[task_id].switch(result)