def testScheduleRemove4(self): '''Schedule-remove the last reference to a tasklet 2''' def func(): stackless.schedule_remove(None) stackless.tasklet(func)() stackless.schedule_remove(None)
def test_schedule_remove(self): main = [] s = stackless.tasklet(lambda:main[0].insert())() with self.switch_trap: self.assertRaisesRegex(RuntimeError, "switch_trap", stackless.schedule_remove) main.append(stackless.getcurrent()) stackless.schedule_remove()
def Pass(self, sequenceNo): """SequenceNo must be a monotonously incrementing integer""" if self.closed: return if self.expected is None: self.expected = sequenceNo if sequenceNo < self.expected: return while sequenceNo > self.expected: me = (sequenceNo, stackless.getcurrent()) heapq.heappush(self.queue, me) self.OnSleep(sequenceNo) stackless.schedule_remove() self.OnWakeUp(sequenceNo) if self.closed: return self.Assert(self.expected == sequenceNo) self.expected += 1 expected = self.expected while self.queue and self.queue[0][0] == expected: self.OnWakingUp(sequenceNo, expected) expected += 1 other = heapq.heappop(self.queue) other[1].insert() if self.lastThrough is not None: self.Assert(self.lastThrough + 1 == sequenceNo) self.lastThrough = sequenceNo
async def coro(): try: # print("coro nesting level: ", stackless.current.nesting_level) stackless.schedule_remove() except: # @IgnorePep8 # print("exception in coro:", sys.exc_info()) raise
def test_schedule_remove(self): main = [] s = stackless.tasklet(lambda: main[0].insert())() with self.switch_trap: self.assertRaisesRegex(RuntimeError, "switch_trap", stackless.schedule_remove) main.append(stackless.getcurrent()) stackless.schedule_remove()
def Pass(self, sequenceNo): if self.closed: return if self.expected is None: self.expected = sequenceNo if sequenceNo < self.expected: return while sequenceNo > self.expected: me = (sequenceNo, stackless.getcurrent()) heapq.heappush(self.queue, me) self.OnSleep(sequenceNo) stackless.schedule_remove() self.OnWakeUp(sequenceNo) if self.closed: return self.Assert(self.expected == sequenceNo) self.expected += 1 expected = self.expected while self.queue and self.queue[0][0] == expected: self.OnWakingUp(sequenceNo, expected) expected += 1 other = heapq.heappop(self.queue) other[1].insert() if self.lastThrough is not None: self.Assert(self.lastThrough + 1 == sequenceNo) self.lastThrough = sequenceNo
def task(self, with_c_state): try: if with_c_state: apply(stackless.schedule_remove, (None,)) else: stackless.schedule_remove(None) finally: self.finally_run_count += 1
async def asyncgen(): try: # print("asyncgen nesting level: ", stackless.current.nesting_level) stackless.schedule_remove() except: # @IgnorePep8 # print("exception in asyncgen:", sys.exc_info()) raise yield 100
def task(self, with_c_state): try: if with_c_state: apply(stackless.schedule_remove, (None, )) else: stackless.schedule_remove(None) finally: self.finally_run_count += 1
def gevent_hub_main(): """Run the gevent hub (+ Syncless) main loop forever. This function is a drop-in replacement of gevent.hub.get_hub.switch() with re-raising the GreeenletExit as SystemExit. See also patch_gevent() for more documentation and restrictions. """ if 'syncless.coio' not in sys.modules: from syncless import best_greenlet return best_greenlet.gevent_hub_main() from gevent import hub if not getattr(hub, 'is_syncless_fake_hub', None): patch_gevent() from syncless import coio main_loop_tasklet = coio.get_main_loop_tasklet() hub_obj = hub.get_hub() hub_type = str(type(hub_obj)) assert hub_type.startswith('<class '), hub_type assert hub_type.endswith(".SynclessFakeHub'>"), hub_type assert hub_obj, 'gevent hub not running' assert hub_obj._tasklet is main_loop_tasklet import stackless assert stackless.current is not main_loop_tasklet if getattr(hub.greenlet, 'is_pts_greenlet_emulated', None): from syncless import greenlet_using_stackless assert hub.greenlet is greenlet_using_stackless.greenlet assert greenlet_using_stackless.current is hub.greenlet.getcurrent() assert hub.MAIN is hub.greenlet.getcurrent() greenlet_using_stackless.current = hub_obj greenlet_using_stackless._insert_after_current_tasklet( main_loop_tasklet) else: # Implement _insert_after_current_tasklet(main_loop_tasklet). if stackless.current.next is stackless.current: main_loop_tasklet.insert() elif stackless.current.next is not main_loop_tasklet: # Below we insert main_loop_tasklet after stackless.current. The # implementation is tricky, see the details in # greenlet_using_stackless.py (search for next.next). Just calling # main_loop_tasklet.insert() would insert main_loop_tasklet before # stackless.current. # # TODO(pts): Present this implementation trick on the conference. main_loop_tasklet.remove() helper_tasklet = stackless.tasklet( lambda: stackless.current.next.next.remove().run())() helper_tasklet.insert() main_loop_tasklet.insert() helper_tasklet.run() helper_tasklet.remove() if hub.greenlet.getcurrent() is hub.MAIN: try: return stackless.schedule_remove() except stackless.greenlet.GreenletExit: raise SystemExit return stackless.schedule_remove()
def task(self, with_c_state): try: if with_c_state: _teststackless.test_cstate( lambda: stackless.schedule_remove(None)) else: stackless.schedule_remove(None) finally: self.finally_run_count += 1
def testScheduleRemoveFail(self): def foo(previous): self.events.append("foo") self.assertFalse(previous.scheduled) previous.insert() self.assertTrue(previous.scheduled) t = stackless.tasklet(foo)(stackless.getcurrent()) stackless.schedule_remove() self.assertEqual(self.events, ["foo"])
def gevent_hub_main(): """Run the gevent hub (+ Syncless) main loop forever. This function is a drop-in replacement of gevent.hub.get_hub.switch() with re-raising the GreeenletExit as SystemExit. See also patch_gevent() for more documentation and restrictions. """ if 'syncless.coio' not in sys.modules: from syncless import best_greenlet return best_greenlet.gevent_hub_main() from gevent import hub if not getattr(hub, 'is_syncless_fake_hub', None): patch_gevent() from syncless import coio main_loop_tasklet = coio.get_main_loop_tasklet() hub_obj = hub.get_hub() hub_type = str(type(hub_obj)) assert hub_type.startswith('<class '), hub_type assert hub_type.endswith(".SynclessFakeHub'>"), hub_type assert hub_obj, 'gevent hub not running' assert hub_obj._tasklet is main_loop_tasklet import stackless assert stackless.current is not main_loop_tasklet if getattr(hub.greenlet, 'is_pts_greenlet_emulated', None): from syncless import greenlet_using_stackless assert hub.greenlet is greenlet_using_stackless.greenlet assert greenlet_using_stackless.current is hub.greenlet.getcurrent() assert hub.MAIN is hub.greenlet.getcurrent() greenlet_using_stackless.current = hub_obj greenlet_using_stackless._insert_after_current_tasklet(main_loop_tasklet) else: # Implement _insert_after_current_tasklet(main_loop_tasklet). if stackless.current.next is stackless.current: main_loop_tasklet.insert() elif stackless.current.next is not main_loop_tasklet: # Below we insert main_loop_tasklet after stackless.current. The # implementation is tricky, see the details in # greenlet_using_stackless.py (search for next.next). Just calling # main_loop_tasklet.insert() would insert main_loop_tasklet before # stackless.current. # # TODO(pts): Present this implementation trick on the conference. main_loop_tasklet.remove() helper_tasklet = stackless.tasklet( lambda: stackless.current.next.next.remove().run())() helper_tasklet.insert() main_loop_tasklet.insert() helper_tasklet.run() helper_tasklet.remove() if hub.greenlet.getcurrent() is hub.MAIN: try: return stackless.schedule_remove() except stackless.greenlet.GreenletExit: raise SystemExit return stackless.schedule_remove()
def ReadAtMost(fd, size): while True: try: return os.read(fd, size) except OSError, e: if e.errno != errno.EAGAIN: raise event.event(HandleWakeup, handle=fd, evtype=event.EV_READ, arg=stackless.current).add() stackless.schedule_remove()
def Accept(sock): while True: try: return sock.accept() except socket.error, e: if e.errno != errno.EAGAIN: raise event.event(HandleWakeup, handle=sock.fileno(), evtype=event.EV_READ, arg=stackless.current).add() stackless.schedule_remove()
def Run(): def watcher(old): while stackless.getruncount() > 1: stackless.schedule() old.insert() with AllowBlock(): stackless.tasklet(watcher)(stackless.getcurrent()) stackless.schedule_remove()
def testTempval(self): def Worker(items): items.append(stackless.schedule()) items.append(stackless.schedule(None)) items.append(stackless.schedule('foo')) items.append(stackless.schedule(42)) items = [] tasklet_obj = stackless.tasklet(Worker)(items) self.assertEqual(None, tasklet_obj.tempval) self.assertEqual([], items) stackless.current.tempval = 5 self.assertEqual(stackless.getcurrent(), stackless.schedule()) self.assertEqual(None, stackless.current.tempval) self.assertEqual(tasklet_obj, tasklet_obj.tempval) self.assertEqual([], items) stackless.schedule() self.assertEqual(None, tasklet_obj.tempval) self.assertEqual([tasklet_obj], items) stackless.schedule() self.assertEqual('foo', tasklet_obj.tempval) self.assertEqual([tasklet_obj, None], items) tasklet_obj.tempval = False stackless.schedule() self.assertEqual([tasklet_obj, None, False], items) self.assertEqual(42, tasklet_obj.tempval) stackless.schedule() self.assertEqual([tasklet_obj, None, False, 42], items) # Upon TaskletExit. self.assertEqual(None, tasklet_obj.tempval) self.assertEqual(1, stackless.getruncount()) self.assertEqual(stackless.getcurrent(), stackless.schedule()) self.assertEqual(None, stackless.current.tempval) self.assertEqual(43, stackless.schedule(43)) # This seems to be a strange Stackless quirk, this should be 43. self.assertEqual(None, stackless.getcurrent().tempval) self.assertEqual(54, stackless.schedule_remove(54)) self.assertEqual(None, stackless.current.tempval) def Worker2(items, main_tasklet): items.append(stackless.getcurrent().tempval) items.append(stackless.schedule(44)) items.append(stackless.current.tempval) main_tasklet.insert() del items[:] stackless.tasklet(Worker2)(items, stackless.getcurrent()) self.assertEqual(55, stackless.schedule_remove(55)) self.assertEqual(None, stackless.current.tempval) self.assertEqual([None, 44, None], items) self.assertRaisesStr(AssertionError, '', stackless.schedule, stackless.bomb(AssertionError)) self.assertRaisesStr(AssertionError, 'foo', stackless.schedule, stackless.bomb(AssertionError, 'foo'))
def send(self, data): if self.balance < 0: receiver = self.queue.pop(0) self.temp = data receiver.insert() self.balance += 1 receiver.run() else: sender = stackless.current self.queue.append((sender, data)) self.balance += 1 stackless.schedule_remove()
def receive(self): if self.balance > 0: sender, retval = self.queue.pop(0) sender.insert() self.balance -= 1 return retval else: receiver = stackless.current self.queue.append(receiver) self.balance -= 1 stackless.schedule_remove() return self.temp
def ReadLine(): while True: try: got = os.read(STDIN_FD, 1024) if not got or '\n' in got: break stdin_read.append(got) except OSError, e: if e[0] != errno.EAGAIN: raise reads.setdefault(STDIN_FD, []).append(stackless.current) stackless.schedule_remove()
def Write(fd, data): while True: try: got = os.write(fd, data) if got == len(data): return if got: data = data[got:] # TODO(pts): Do with less copy except OSError, e: if e.errno != errno.EAGAIN: raise event.event(HandleWakeup, handle=fd, evtype=event.EV_WRITE, arg=stackless.current).add() stackless.schedule_remove()
def Run(): """A simple runner, usable from any tasklet (stackless.run only works on the main tasklet """ def watcher(old): while stackless.getruncount() > 1: stackless.schedule() old.insert() with AllowBlock(): stackless.tasklet(watcher)(stackless.getcurrent()) stackless.schedule_remove()
def task_outer(): stackless.schedule_remove((0, sys.exc_info())) try: raise e1 except Exception: stackless.schedule_remove((1, sys.exc_info())) task_inner() stackless.schedule_remove((5, sys.exc_info())) stackless.schedule_remove((6, sys.exc_info()))
def f(self): tlet = stackless.current for result in self.checkSignatureNamedArgs( stackless.schedule_remove, 0, None, "retval", tlet): self.assertIs(tlet, result) o = object() self.assertIs(o, stackless.schedule_remove(o)) done.append(True)
def foo(arg): nonlocal got_TaskletExit try: res = stackless.schedule_remove(arg) except TaskletExit: got_TaskletExit = True raise return res
def testScheduleRemoveLast(self): def Worker1(): stackless.schedule_remove() assert 0 def Worker2(): stackless.schedule_remove() 1 / 0 stackless.tasklet(Worker1)() stackless.tasklet(Worker2)() try: # In Stackless 2.6.5, stackless.main will be inserted back when the # last tasklet gets removed from the runnables list. stackless.schedule_remove() except ZeroDivisionError: # In Stackless 2.6.4, the last tasklet (Worker2) won't be removed (but # schedule_remove would be equivalent to schedule). assert not hasattr(stackless, '_tasklet_wrapper') # Not greenstackless. assert '2.6.4 ' <= sys.version < '2.6.5 '
def task_inner(): stackless.schedule_remove((2, sys.exc_info())) try: raise e2 except Exception: stackless.schedule_remove((3, sys.exc_info())) stackless.schedule_remove((4, sys.exc_info()))
def generator(asyncgen): """Create a generator-iterator, that iterates over *asyncgen* This generator-function creates a generator-iterator, that iterates over the given asynchronous iterable. The returned generator-iterator must be called from code, that is executed by :func:`new_generator_coroutine`. :param asyncgen: an asynchronous iterable object :returns: a generator iterator :raises RuntimeError: the generator raises RuntimeError, if called from outside of :func:`new_generator_coroutine`. """ # See Python language reference 8.8.2. The async for statement if not _new_generator_coroutine.runcount: raise RuntimeError("Can't call generator() from tasklet " + repr(stackless.current)) asyncgen = type(asyncgen).__aiter__(asyncgen) cls = type(asyncgen) # first method is always __anext__ method = cls.__anext__ value = () while True: try: value = stackless.schedule_remove((_AWAIT, method(asyncgen, *value))) except StopAsyncIteration: return try: value = ((yield value),) method = cls.asend except GeneratorExit: try: stackless.schedule_remove((_AWAIT, cls.aclose(asyncgen))) except StopAsyncIteration: pass raise except Exception: value = sys.exc_info() method = cls.athrow
def task_inner(): stackless.schedule_remove((2, sys.exc_info())) yield 3 try: raise e2 except Exception: yield 4 stackless.schedule_remove((5, sys.exc_info())) yield 6 yield 7 stackless.schedule_remove((8, sys.exc_info()))
def await_coroutine(coroutine): """await a coroutine A normal function (or method or other callable) may use this function to await an awaitable object, if the function has been directly or indirectly called by :func:`new_generator_coroutine`. :param coroutine: the coroutine to be awaited :type coroutine: :class:`~collections.abc.Coroutine` or :class:`~collections.abc.Generator` :returns: the value returned by *coroutine* :raises RuntimeError: if called from outside of :func:`new_generator_coroutine`. """ if not _new_generator_coroutine.runcount: raise RuntimeError("Can't call await_coroutine from tasklet " + repr(stackless.current)) if not isinstance(coroutine, (collections.abc.Coroutine, collections.abc.Generator)): raise TypeError("argument is neither a coroutine nor a generator") return stackless.schedule_remove((_AWAIT, coroutine))
def func(): stackless.schedule_remove(None)
def stackless_quit(): #kills all running tasklets: while stackless.runcount > 0: stackless.schedule_remove()
if len(sys.argv) == 1: sys.argv = [sys.argv[0], 'build'] os.system('rm -rf build') setup(ext_modules=[Extension('fooo', ['fooo.c'])]) # Load fooo.so sys.path[:0] = ['build/lib.%s-%s' % (get_platform(), sys.version[0:3])] import fooo import stackless import sys # No segfault if we call SoftMainLoop instead of fooo.SoftMainLoop. #stackless.enable_softswitch(0) #def SoftMainLoop(): # stackless.schedule() # stackless.schedule() # raise AssertionError stackless.tasklet(fooo.SoftMainLoop)() def Work(): print 'exiting' sys.exit() stackless.tasklet(Work)() print 'last breath' stackless.schedule_remove()
def CooperativeRemove(name): while True: events.append(name + '.corm') stackless.schedule_remove()
def testLastChannel(self): channel_obj = stackless.channel() self.assertRaisesStr( RuntimeError, 'Deadlock: the last runnable tasklet cannot be blocked.', channel_obj.receive) self.assertRaisesStr( RuntimeError, 'Deadlock: the last runnable tasklet cannot be blocked.', channel_obj.send, 55) tasklet_obj = stackless.tasklet(channel_obj.receive)() self.assertFalse(tasklet_obj.blocked) stackless.schedule_remove() # Blocking re-adds us (stackless.main). self.assertTrue(tasklet_obj.blocked) self.assertEqual(-1, channel_obj.balance) tasklet_obj.kill() self.assertEqual(0, channel_obj.balance) self.assertFalse(tasklet_obj.blocked) self.assertEqual(1, stackless.getruncount()) stackless.tasklet(lambda: 1 / 0)() self.assertRaisesStr( StopIteration, 'the main tasklet is receiving without a sender available.', channel_obj.receive) self.assertEqual(1, stackless.getruncount()) self.assertRaisesStr( RuntimeError, 'Deadlock: the last runnable tasklet cannot be blocked.', channel_obj.send, 55) # The AssertionError will get ignored and converted to a StopIteration. # (That's a bit odd behavior of Stackless.) def LazyWorker(): stackless.schedule() stackless.schedule() stackless.schedule() assert 0 tasklet_obj = stackless.tasklet(LazyWorker)() stackless.schedule() self.assertEqual(2, stackless.getruncount()) self.assertTrue(tasklet_obj.alive) self.assertRaisesStr( StopIteration, 'the main tasklet is receiving without a sender available.', channel_obj.receive) self.assertFalse(tasklet_obj.alive) self.assertEqual(1, stackless.getruncount()) self.assertRaisesStr( RuntimeError, 'Deadlock: the last runnable tasklet cannot be blocked.', channel_obj.send, 55) def ValueWorker(): stackless.schedule() raise ValueError def DivideWorker(): stackless.schedule() 1 / 0 tasklet1 = stackless.tasklet(ValueWorker)() tasklet2 = stackless.tasklet(DivideWorker)() stackless.schedule() self.assertEqual(3, stackless.getruncount()) self.assertTrue(tasklet1.alive) self.assertTrue(tasklet2.alive) self.assertRaises(ValueError, channel_obj.receive) self.assertFalse(tasklet1.alive) self.assertTrue(tasklet2.alive) self.assertEqual(2, stackless.getruncount()) self.assertRaisesStr( StopIteration, 'the main tasklet is sending without a receiver available.', channel_obj.send, 55) tasklet2.kill()
def Worker2(): stackless.schedule_remove() 1 / 0
from distutils.core import setup from distutils.util import get_platform # Compile fooo.c to fooo.so if len(sys.argv) == 1: sys.argv = [sys.argv[0], 'build'] os.system('rm -rf build') setup(ext_modules=[Extension('fooo', ['fooo.c'])]) # Load fooo.so sys.path[:0] = ['build/lib.%s-%s' % (get_platform(), sys.version[0 : 3])] import fooo import stackless import sys # No segfault if we call SoftMainLoop instead of fooo.SoftMainLoop. #stackless.enable_softswitch(0) #def SoftMainLoop(): # stackless.schedule() # stackless.schedule() # raise AssertionError stackless.tasklet(fooo.SoftMainLoop)() def Work(): print 'exiting' sys.exit() stackless.tasklet(Work)() print 'last breath' stackless.schedule_remove()
def func(self): stackless.schedule_remove() self.fail("We shouldn't be here")
def remove(): stackless.schedule_remove(retval=None)
def tasklet_action(self): stackless.schedule_remove() # pause it self.taskletExecuted = True
def F(other_ref, x): stackless.schedule_remove()
def Worker1(): stackless.schedule_remove() assert 0
def Sleep(timeout): deadlines.append((time.time() + float(timeout), stackless.current)) stackless.schedule_remove()
sys.stdout.flush() answer = sys.stdin.readline() assert answer answer = answer.strip() try: age = int(answer) except ValueError: print "Please enter an integer." continue if age < 3: print "That would be too young. Please enter a valid age." continue assert age != 111, "simulated bug" if age == 222: print "Canceling the timeout." timeout_obj.cancel() elif age == 333: print "Canceling the timeout to 1 second, starting from now." timeout_obj.change(1) else: final_age = age break assert 2 == stackless.getruncount() if final_age is None: # Timed out. print "You were too slow entering your age." else: print "Got age: %r." % final_age if len(sys.argv) > 1: # Run until all tasklets exit. This doesn't work anymore with libev. stackless.schedule_remove(None)