def _start(self, function, args, kwargs): r, v = function(*args, **kwargs) #r is the tasklet to switch back to, v is the value passed to it # print "end %s %s" % ( id(stackless.getcurrent()), id(r) ) with atomic(): self.value = v r.run() #no switch, let this tasklet continue to end
def iwait(objects, timeout=None, raise_timeout=False): """ A generator that returns objects as they become ready. The total waiting time will not exceed "timeout" if provided. Raises TimeoutError if a timeout occurs. """ channel = stacklesslib.util.QueueChannel() count = 0 callbacks = {} def get_cb(obj): def cb(waitable): waitable.remove_done_callback(callbacks.pop(waitable)) channel.send(waitable) callbacks[obj] = cb return cb try: with atomic(): for obj in objects: obj.add_done_callback(get_cb(obj)) count += 1 if timeout is not None: # handle 0 timeouts by not blocking at all if timeout == 0: with atomic(): while channel.balance > 0: count -= 1 yield channel.receive() if count: raise TimeoutError() else: timeouts = stacklesslib.util.Timeouts(timeout) for i in xrange(count): with timeouts.timeout(): yield channel.receive() else: for i in xrange(count): yield channel.receive() finally: for obj, cb in callbacks.items(): obj.remove_done_callback(cb)
def _start(self, function, args, kwargs): self.prev.remove() self.prev = None r, v = function(*args, **kwargs) #r is the tasklet to switch back to, v is the value passed to it # print "end %s %s" % ( id(stackless.getcurrent()), id(r) ) with atomic(): self.value = v self.previous = None # the target does not remove us r.run()
def start(self, t, args=(), kwargs={}): """Start a context previously created""" prev = stackless.getcurrent() # NOTE: Disable this test to enable a weird crash in stackless when running the greenlet unittests if t.thread_id != prev.thread_id: raise error("can't switch to a different thread") # print "start %s %s" %(id(prev), id(t)) with atomic(): t(args, kwargs) t.switch() return self._return()
def switch(self, target, value=None): prev = stackless.getcurrent() # print "sw %s(%s) %s(%s)" % (id(prev), prev.thread_id, id(target), target.thread_id) if prev is target: return value if target.thread_id != prev.thread_id: raise error("can't switch to a different thread") with atomic(): self.value = value target.switch() return self._return()
def get(self, block=True, timeout=None): """ Get the result of the tasklet or raise exception """ with atomic(): if not self._done and block: self.join(timeout) if not self._done: raise TimeoutError if self._error: raise self._error[0], self._error[1], self._error[2] return self._value
def switch(self, target, value=None): prev = stackless.getcurrent() # print "sw %s %s" % (id(prev), id(target)) if prev is target: return value if target.thread_id != prev.thread_id: raise error("can't switch to a different thread") with atomic(): self.prev = prev self.value = value target.run() assert self.prev != prev return self._return()
def swait(waitable, timeout=None): """ A simple wait function to wait for a single waitable. Returns the waitable or raises TimeoutError. """ channel = stacklesslib.util.QueueChannel() with atomic(): waitable.add_done_callback(channel.send) try: with stacklesslib.util.timeout(timeout): return channel.receive() finally: waitable.remove_done_callback(channel.send)
def receive(self): with atomic(): self._notify_state_change(-1) return super(WaitChannelMixin, self).receive()
def send_throw(self, exc, value=None, tb=None): with atomic(): self._notify_state_change(1) super(WaitChannelMixin, self).send_throw(exc, value, tb)
def send_exception(self, exc, *args): with atomic(): self._notify_state_change(1) super(WaitChannelMixin, self).send_exception(exc, *args)
def send(self, value): with atomic(): self._notify_state_change(1) super(WaitChannelMixin, self).send(value)