def send(self, item): if self._waiters and not self._dataqueue: self._dataqueue.append(item) if self.preference is -1: scheduler.schedule(greenlet.getcurrent()) self._waiters.popleft().switch() else: scheduler.schedule(self._waiters.popleft()) else: self._dataqueue.append(item) self._waiters.append(greenlet.getcurrent()) state.mainloop.switch()
def acquire(self, blocking=True): """if the lock is owned by a different greenlet, block until it is fully released. then increment the acquired count by one""" current = greenlet.getcurrent() if self._owner is current: self._count += 1 return True if self._locked and not blocking: return False if self._locked: self._waiters.append(greenlet.getcurrent()) state.mainloop.switch() self._owner = current self._locked = True self._count = 1 return True
def receive(self): if self._closing and not self._dataqueue: raise StopIteration() if self._dataqueue: item = self._dataqueue.popleft() sender = self._waiters.popleft() if self.preference is 1: scheduler.schedule(greenlet.getcurrent()) sender.switch() else: scheduler.schedule(sender) return item else: self._waiters.append(greenlet.getcurrent()) state.mainloop.switch() return self._dataqueue.pop()
def acquire(self, blocking=True): "lock or decrement the semaphore" if self._value: self._value -= 1 return True elif not blocking: return False self._waiters.append(greenlet.getcurrent()) state.mainloop.switch() return True
def acquire(self, blocking=True): "lock the lock, or block until it is available" if not blocking: locked_already = self._locked self._locked = True return not locked_already if self._locked: self._waiters.append(greenlet.getcurrent()) state.mainloop.switch() self._locked = True return True
def release(self): """decrement the owned count by one. if it reaches zero, fully release the lock, waking up a waiting greenlet""" if not self._locked or self._owner is not greenlet.getcurrent(): raise RuntimeError("cannot release un-acquired lock") self._count -= 1 if self._count == 0: self._owner = None if self._waiters: state.awoken_from_events.add(self._waiters.popleft()) else: self._locked = False
def wait(self, timeout=None): """wait to be woken up by the condition you must have acquired the underlying lock first""" if not self._is_owned(): raise RuntimeError("cannot wait on un-acquired lock") self._lock.release() current = greenlet.getcurrent() self._waiters.append(current) if timeout is not None: @scheduler.schedule_in(timeout) def hit_timeout(): self._waiters.remove(current) current.switch() state.mainloop.switch() self._lock.acquire()
def wait(self, timeout=None): """pause the current coroutine until this event is set if the set() method has been called, this method will not block at all. otherwise it will block until the set() method is called""" if self._is_set: return current = greenlet.getcurrent() # the waiting greenlet if timeout is not None: self._active_timeouts.add(current) @scheduler.schedule_in(timeout) def hit_timeout(): if current in self._active_timeouts: self._active_timeouts.remove(current) self._awoken_by_timeout.add(current) current.switch() self._waiters.append(current) state.mainloop.switch() if current in self._awoken_by_timeout: self._awoken_by_timeout.remove(current) klass, exc, tb = None, None, None for cb in self._timeout_callbacks: try: cb() except Exception: if klass is None: klass, exc, tb = sys.exc_info() if klass is not None: raise klass, exc, tb
def pause_until(unixtime): '''pause and reschedule the current greenlet until a set time, then switch to the next''' schedule_at(unixtime, greenlet.getcurrent()) mainloop.switch()
def pause(): 'pause and reschedule the current greenlet and switch to the next' schedule(greenlet.getcurrent()) mainloop.switch()
# wait for timeouts and events while we have nothing to run while not state.to_run: time.sleep(NOTHING_TO_DO_PAUSE) # no need to check the simple cooperative yields again here _repopulate(include_paused=False) state.to_run.popleft().switch() except Exception, exc: if sys: _consume_exception(*sys.exc_info()) state.mainloop = mainloop # rig it so the next mainloop.switch() call will definitely put us back here state.to_run.appendleft(greenlet.getcurrent()) # then prime the pump. if there is a traceback before the mainloop greenlet # has a chance to get into its 'try' block, the mainloop will die of that # traceback and it will wind up being raised in the main greenlet @schedule def f(): pass mainloop.switch() def _consume_exception(klass, exc, tb): _purge_exception_handlers() for weak in _exception_handlers: try: weak()(klass, exc, tb)
def __setattr__(self, name, value): self.data.setdefault(greenlet.getcurrent(), {})[name] = value
def __getattr__(self, name): local = self.data.setdefault(greenlet.getcurrent(), {}) if name not in local: raise AttributeError, "Local object has no attribute %s" % name return local[name]
def _is_owned(self): return self._owner is greenlet.getcurrent()