Example #1
0
    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'))
Example #2
0
  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'))
Example #3
0
 def _doRemoteError(self, fault):
     try:
         ntype, value = fault.type, fault.value
         if isinstance(value, ntype):
             b = bomb(ntype, value)
         else:
             b = bomb(ntype, ntype(value))
         b.raise_()
     except Exception, e:
         self._status = FutureResult.STATUS_ERROR
         self._exception = e
         ftlog.error()
def SendException(tasklet, exc_info):
    """Send exception to tasklet, even if it's blocked on a channel.

  To get the tasklet is activated (to handle the exception) after
  SendException, call tasklet.run() after calling SendException.

  tasklet.insert() is called automatically to ensure that it eventually gets
  scheduled.
  """
    if not isinstance(exc_info, list) and not isinstance(exc_info, tuple):
        raise TypeError
    if tasklet == stackless.current:
        if len(exc_info) < 3:
            exc_info = list(exc_info) + [None, None]
        raise exc_info[0], exc_info[1], exc_info[2]
    bomb = stackless.bomb(*exc_info)
    if tasklet.blocked:
        c = tasklet._channel
        old_preference = c.preference
        c.preference = 1  # Prefer the sender.
        for i in xrange(-c.balance):
            c.send(bomb)
        c.preference = old_preference
    else:
        tasklet.tempval = bomb
    tasklet.insert()
def SendException(tasklet, exc_info):
    """Send exception to tasklet, even if it's blocked on a channel.

  To get the tasklet is activated (to handle the exception) after
  SendException, call tasklet.run() after calling SendException.

  tasklet.insert() is called automatically to ensure that it eventually gets
  scheduled.
  """
    if not isinstance(exc_info, list) and not isinstance(exc_info, tuple):
        raise TypeError
    if tasklet == stackless.current:
        if len(exc_info) < 3:
            exc_info = list(exc_info) + [None, None]
        raise exc_info[0], exc_info[1], exc_info[2]
    bomb = stackless.bomb(*exc_info)
    if tasklet.blocked:
        c = tasklet._channel
        old_preference = c.preference
        c.preference = 1  # Prefer the sender.
        for i in xrange(-c.balance):
            c.send(bomb)
        c.preference = old_preference
    else:
        tasklet.tempval = bomb
    tasklet.insert()
Example #6
0
File: run.py Project: lordsky/hall0
 def send_exception_nowait(self, ntype, value):
     if self.balance == 0:
         self.exc = (ntype, value)
     else:
         if isinstance(value, ntype):
             self.send(bomb(ntype, value))
         else:
             self.send_exception(ntype, value)
Example #7
0
 def send_exception_nowait(self, exp_type, exp_value):
     if self.balance == 0:
         self.exc = (exp_type, exp_value)
     else:
         if isinstance(exp_value, exp_type):
             self.send(stackless.bomb(exp_type, exp_value))
         else:
             self.send_exception(exp_type, exp_value)
Example #8
0
 def send_exception_nowait(self, ntype, value):
     if self.balance == 0:
         self.exc = (ntype, value)
     else:
         if isinstance(value, ntype):
             self.send(bomb(ntype, value))
         else:
             self.send_exception(ntype, value)
Example #9
0
 def test_bomb(self):
     try:
         1/0
     except:
         import sys
         b = stackless.bomb(*sys.exc_info())
     assert b.type is ZeroDivisionError
     assert str(b.value).startswith('integer division')
     assert b.traceback is not None
Example #10
0
 def test_bomb(self):
     try:
         1 / 0
     except:
         import sys
         b = stackless.bomb(*sys.exc_info())
     assert b.type is ZeroDivisionError
     assert str(b.value).startswith('integer division')
     assert b.traceback is not None
Example #11
0
    def send_exception_noblock(self, ntype, value):
        '''
        send exception in non-block style

        :param ntype:   subclass of BaseException
        :param value:   class instance or parameters
        :return: void
        '''
        if self.balance == 0:
            self.nbQueue.append((1, ntype, value))
        else:
            assert issubclass(ntype,BaseException)
            if isinstance(value, ntype):
                self.send(stackless.bomb(ntype, value))
            else:
                self.send_exception(ntype, value)
  def throw(self, typ=None, val=None, tb=None):
    global current
    if not typ:
      typ = GreenletExit
    target = self
    del self  # Save memory and drop reference.
    while True:  # This logic is tested in GreenletTest.testThrow.
      if not target.dead:
        if target._tasklet:
          break
        target.dead = True
        target.__dict__.pop('run', None)  # Keep methods of subclasses.
        if issubclass(typ, GreenletExit):
          # This is tested by GreenletUsingStacklesstest.testParentOnKill.
          apply_args = [(target.parent.switch, (typ(val),))]
          del target, typ, val, tb  # Save memory and drop reference.
          return apply(*apply_args.pop())
      target = target.parent
    if target is current:
      raise typ, val, tb
    target._tasklet.tempval = stackless.bomb(typ, val, tb)
    del typ, val, tb  # Save memory and drop reference.
    # Don't call target.switch, it might be overridden in a subclass.

    # The following code is duplicated between .switch() and .throw(), but
    # it would be too slow to refactor to a function because of the extra
    # references to `target'.
    current = target
    target = [target._tasklet.remove().run]
    try:
      retval = target.pop()()
    except TaskletExit:
      return _handle_tasklet_exit_in_switch(*sys.exc_info())
    except:
      stackless.current.next.remove()
      assert current._tasklet is stackless.current
      raise
    stackless.current.next.remove()
    assert current._tasklet is stackless.current
    return retval
    def throw(self, typ=None, val=None, tb=None):
        global current
        if not typ:
            typ = GreenletExit
        target = self
        del self  # Save memory and drop reference.
        while True:  # This logic is tested in GreenletTest.testThrow.
            if not target.dead:
                if target._tasklet:
                    break
                target.dead = True
                target.__dict__.pop('run', None)  # Keep methods of subclasses.
                if issubclass(typ, GreenletExit):
                    # This is tested by GreenletUsingStacklesstest.testParentOnKill.
                    apply_args = [(target.parent.switch, (typ(val), ))]
                    del target, typ, val, tb  # Save memory and drop reference.
                    return apply(*apply_args.pop())
            target = target.parent
        if target is current:
            raise typ, val, tb
        target._tasklet.tempval = stackless.bomb(typ, val, tb)
        del typ, val, tb  # Save memory and drop reference.
        # Don't call target.switch, it might be overridden in a subclass.

        # The following code is duplicated between .switch() and .throw(), but
        # it would be too slow to refactor to a function because of the extra
        # references to `target'.
        current = target
        target = [target._tasklet.remove().run]
        try:
            retval = target.pop()()
        except TaskletExit:
            return _handle_tasklet_exit_in_switch(*sys.exc_info())
        except:
            stackless.current.next.remove()
            assert current._tasklet is stackless.current
            raise
        stackless.current.next.remove()
        assert current._tasklet is stackless.current
        return retval
Example #14
0
 def Bomber(tasklet_obj, msg):
   tasklet_obj.tempval = stackless.bomb(AssertionError, msg)
Example #15
0
 def SendBomb():
     assert c.send(stackless.bomb(typ, val, tb1)) is None
     target._tasklet.tempval = e
 except TaskletExit, e:
   # This doesn't happen with gevent in a worker greenlet, because the
   # exception handler in the hub (gevent.core.__event_handler) stops the
   # TaskletExit from propagating.
   # Still true (but del'ed above): assert greenlet_obj is current
   target = current.parent
   while target.dead:
     target = target.parent
   if target._tasklet is None:
     _first_switch(target, e)
   else:
     target._tasklet.tempval = e
 except:
   # Still true (but del'ed above): assert greenlet_obj is current
   bomb_obj = stackless.bomb(*sys.exc_info())
   target = current.parent
   while True:  # This logic is tested in GreenletTest.testThrow.
     if not target.dead:
       if target._tasklet:
         break
       # This is tested in greenlet5 of GreenletTest.testSwitchToParent.
       target.dead = True
       target.__dict__.pop('run', None)  # Keep methods of subclasses.
     target = target.parent
   target._tasklet.tempval = bomb_obj
   del bomb_obj  # Save memory.
 if getattr(current, '_is_revived', False):
   current.dead = True
   # Not inserting the placeholder, because the parent wouldn't remove it.
   _insert_after_current_tasklet(target._tasklet)
Example #17
0
    def testStackless(self):
        events = []

        def Divide(a, b):
            return a / b

        def Worker(name, c):
            while True:
                events.append(name + '.wait')
                events.append('%s/%s' % (name, c.receive()))

        def Single(name):
            events.append(name + '.single')

        def Cooperative(name):
            while True:
                events.append(name + '.coop')
                stackless.schedule()

        def CooperativeRemove(name):
            while True:
                events.append(name + '.corm')
                stackless.schedule_remove()

        def Run():
            while True:
                events.append('schedule')
                i = len(events)
                stackless.schedule()
                if i == len(events):
                    break
            events.append('done')

        c = stackless.channel()

        self.assertTrue(stackless.current is stackless.getmain())
        self.assertTrue(stackless.getcurrent() is stackless.main)
        self.assertEqual(1, stackless.getruncount())
        self.assertTrue(stackless.current is stackless.getcurrent().next)
        self.assertTrue(stackless.current is stackless.getcurrent().prev)
        ta = stackless.tasklet(Worker)('A', c)
        tb = stackless.tasklet(Worker)('B', c)
        tc = stackless.tasklet(Worker)('C', c)
        td = stackless.tasklet().bind(Worker)('D', c)
        self.assertEqual(5, stackless.getruncount())
        self.assertTrue(td is stackless.current.prev)
        self.assertTrue(ta is stackless.getcurrent().next)
        self.assertTrue(td.next is stackless.current)
        self.assertTrue(td.prev is tc)

        self.assertEqual(c.preference, -1)
        self.assertEqual(c.balance, 0)
        del events[:]
        events.append('send')
        self.assertEqual(5, stackless.getruncount())
        self.assertEqual(None, c.send('msg'))
        self.assertEqual(1, stackless.getruncount())
        Run()
        self.assertEqual(
            ' '.join(events),
            'send A.wait A/msg A.wait B.wait C.wait D.wait schedule done')

        self.assertEqual(c.preference, -1)
        self.assertEqual(c.balance, -4)
        del events[:]
        events.append('send')
        c.preference = 0  # same as c.preference = 1
        self.assertEqual(1, stackless.getruncount())
        self.assertEqual(None, c.send('msg'))
        self.assertEqual(2, stackless.getruncount())
        Run()
        #print ' '.join(events)
        self.assertEqual(' '.join(events),
                         'send schedule A/msg A.wait schedule done')

        self.assertEqual(c.preference, 0)
        self.assertEqual(c.balance, -4)
        del events[:]
        c.preference = 1
        events.append('send')
        self.assertEqual(1, stackless.getruncount())
        self.assertEqual(None, c.send('msg'))
        self.assertEqual(2, stackless.getruncount())
        Run()
        self.assertEqual(' '.join(events),
                         'send schedule B/msg B.wait schedule done')

        self.assertEqual(c.preference, 1)
        del events[:]
        c.preference = 2  # same as c.preference = 1
        events.append('send')
        self.assertEqual(1, stackless.getruncount())
        self.assertEqual(None, c.send('msg'))
        self.assertEqual(None, c.send('msg'))
        self.assertEqual(3, stackless.getruncount())
        Run()
        self.assertEqual(
            ' '.join(events),
            'send schedule C/msg C.wait D/msg D.wait schedule done')
        # Now the doubly-linked list is (d, main, a, b, c). Why?

        self.assertEqual(c.balance, -4)
        del events[:]
        c.preference = 5
        events.append('send')
        self.assertEqual(c.balance, -4)
        self.assertEqual(1, stackless.getruncount())
        t = stackless.tasklet(Single)
        self.assertEqual(1, stackless.getruncount())
        self.assertTrue(t is t('T'))
        self.assertEqual(2, stackless.getruncount())
        t.remove()
        self.assertEqual(1, stackless.getruncount())
        self.assertEqual(t, t.insert())
        self.assertEqual(2, stackless.getruncount())
        self.assertEqual(None, c.send('msg1'))
        self.assertEqual(c.balance, -3)
        self.assertEqual(None, c.send('msg2'))
        self.assertEqual(None, c.send('msg3'))
        self.assertEqual(None, c.send('msg4'))
        self.assertEqual(6, stackless.getruncount())
        events.append('a4')
        self.assertEqual(c.balance, 0)
        self.assertEqual(None, c.send('msg5'))
        self.assertEqual(5, stackless.getruncount())
        events.append('a5')
        self.assertEqual(None, c.send('msg6'))
        self.assertEqual(5, stackless.getruncount())
        Run()
        self.assertEqual(
            ' '.join(events),
            'send a4 T.single A/msg1 A.wait a5 B/msg2 B.wait schedule C/msg3 C.wait D/msg4 D.wait A/msg5 A.wait B/msg6 B.wait schedule done'
        )

        self.assertTrue(stackless.getcurrent() is stackless.current.next)
        self.assertTrue(stackless.getcurrent() is stackless.current.prev)

        del events[:]
        self.assertEqual(c.balance, -4)
        c.preference = 42
        self.assertEqual(None, c.send('msg1'))
        self.assertEqual(c.balance, -3)
        self.assertTrue(tc is stackless.getcurrent().next)
        self.assertTrue(tc is stackless.current.prev)
        self.assertTrue(tc.prev is stackless.getcurrent())
        self.assertTrue(tc.next is stackless.current)
        self.assertEqual(None, c.send('msg2'))
        self.assertEqual(c.balance, -2)
        self.assertTrue(tc is stackless.getcurrent().next)
        self.assertTrue(td is stackless.current.prev)
        self.assertTrue(td.next is stackless.getcurrent())
        self.assertTrue(td.prev is tc)
        self.assertEqual(None, c.send('msg3'))
        self.assertEqual(c.balance, -1)
        self.assertTrue(tc is stackless.current.next)
        self.assertTrue(ta is stackless.getcurrent().prev)
        self.assertTrue(ta.next is stackless.current)
        self.assertTrue(ta.prev is td)
        self.assertEqual(' '.join(events), '')
        self.assertEqual(4, stackless.getruncount())
        t = stackless.tasklet(Single)('T')
        self.assertTrue(t is stackless.getcurrent().prev)
        self.assertTrue(ta is t.prev)
        self.assertTrue(t.alive)
        self.assertEqual(5, stackless.getruncount())
        t.remove()
        #self.assertTrue(t.next is None  # NotImplementedError in greenstackless)
        self.assertTrue(ta is stackless.current.prev)
        self.assertTrue(t.alive)
        self.assertEqual(4, stackless.getruncount())
        t.run()
        self.assertEqual(4, stackless.getruncount())
        self.assertTrue(not t.alive)
        self.assertEqual(' '.join(events), 'T.single')
        del events[:]
        td.run()
        self.assertEqual(' '.join(events), 'D/msg2 D.wait A/msg3 A.wait')
        del events[:]
        self.assertEqual(c.balance, -3)
        self.assertTrue(tc is stackless.getcurrent().next)
        self.assertTrue(tc is stackless.current.prev)
        self.assertTrue(tc.prev is stackless.getcurrent())
        self.assertTrue(tc.next is stackless.current)
        tc.run()
        self.assertEqual(' '.join(events), 'C/msg1 C.wait')
        del events[:]
        self.assertEqual(c.balance, -4)
        self.assertTrue(stackless.getcurrent() is stackless.current.next)
        self.assertTrue(stackless.getcurrent() is stackless.current.prev)

        t = stackless.tasklet(Cooperative)('T')
        r = stackless.tasklet(CooperativeRemove)('R')
        u = stackless.tasklet(Cooperative)('U')
        self.assertEqual(4, stackless.getruncount())
        del events[:]
        stackless.schedule()
        self.assertEqual(' '.join(events), 'T.coop R.corm U.coop')
        self.assertEqual(3, stackless.getruncount())
        del events[:]
        stackless.schedule()
        self.assertEqual(' '.join(events), 'T.coop U.coop')
        self.assertEqual(3, stackless.getruncount())
        del events[:]
        t.kill()  # This involves t.run(), so u gets run as well.
        self.assertEqual(' '.join(events), 'U.coop')
        self.assertEqual(2, stackless.getruncount())
        r.kill()
        self.assertEqual(2, stackless.getruncount())
        r.kill()
        self.assertEqual(2, stackless.getruncount())
        u.kill()
        self.assertEqual(1, stackless.getruncount())

        typ, val, tb1 = None, None, None
        try:
            Divide(42, 0)
        except ZeroDivisionError:
            typ, val, tb1 = sys.exc_info()
        self.assertTrue(typ is ZeroDivisionError)

        tb2 = None
        try:
            if hasattr(stackless.getcurrent(), 'throw'):  # greenstackless
                stackless.current.throw(typ, val, tb1)
            else:  # Stackless
                stackless.getcurrent().tempval = stackless.bomb(typ, val, tb1)
                stackless.current.run()
        except:
            self.assertTrue(sys.exc_info()[0] is typ)
            self.assertTrue(sys.exc_info()[1] is val)
            tb2 = sys.exc_info()[2]
            tb3 = tb2 and tb2.tb_next
            tb4 = tb3 and tb3.tb_next
            # greenstackless adds 2 frames.
            self.assertTrue(tb1 in (tb2, tb3, tb4))
        self.assertTrue(tb2)

        self.assertEqual(-4, c.balance)
        ta.kill()
        self.assertEqual(-3, c.balance)
        td.kill()
        self.assertEqual(-2, c.balance)
        tc.kill()
        self.assertEqual(-1, c.balance)
        tb.kill()
        self.assertEqual(0, c.balance)

        tb2 = None
        self.assertEqual(0, c.balance)
        c.preference = 1

        def SendBomb():
            assert c.send(stackless.bomb(typ, val, tb1)) is None

        stackless.tasklet(SendBomb)()
        try:
            c.receive()
        except:
            self.assertTrue(sys.exc_info()[0] is typ)
            self.assertTrue(sys.exc_info()[1] is val)
            tb2 = sys.exc_info()[2]
            tb3 = tb2 and tb2.tb_next
            tb4 = tb3 and tb3.tb_next
            tb5 = tb4 and tb4.tb_next
            # greenstackless adds 3 frames (including c.receive() etc.)
            self.assertTrue(tb1 in (tb2, tb3, tb4, tb5))
        self.assertTrue(tb2)

        tb2 = None
        self.assertEqual(0, c.balance)
        c.preference = 1

        def SendBomb():
            assert c.send(stackless.bomb(typ, val, tb1)) is None

        stackless.tasklet(SendBomb)()
        try:
            c.receive()
        except:
            self.assertTrue(sys.exc_info()[0] is typ)
            self.assertTrue(sys.exc_info()[1] is val)
            tb2 = sys.exc_info()[2]
            tb3 = tb2 and tb2.tb_next
            tb4 = tb3 and tb3.tb_next
            tb5 = tb4 and tb4.tb_next
            # greenstackless adds 3 frames (including c.receive() etc.)
            self.assertTrue(tb1 in (tb2, tb3, tb4, tb5))
        self.assertTrue(tb2)

        tb2 = None

        def RaiseException(task):
            task.raise_exception(ValueError, 42)

        stackless.tasklet(RaiseException)(stackless.getcurrent())
        try:
            stackless.schedule()
        except:
            self.assertTrue(sys.exc_info()[0] is ValueError)
            self.assertEqual(str(sys.exc_info()[1]), '42')
            tb2 = sys.exc_info()[2]
            # Don't check the traceback (tb2), should be in stackless.schedule().
        self.assertTrue(tb2)

        tb2 = None
        self.assertEqual(0, c.balance)
        c.preference = 1

        def SendException(task):
            assert c.send_exception(ValueError, 43) is None

        stackless.tasklet(SendException)(stackless.current)
        try:
            c.receive()
        except:
            self.assertTrue(sys.exc_info()[0] is ValueError)
            self.assertEqual(str(sys.exc_info()[1]), '43')
            tb2 = sys.exc_info()[2]
            # Don't check the traceback (tb2), should be in stackless.schedule().
        self.assertTrue(tb2)
Example #18
0
 def Bomber(tasklet_obj, msg):
     tasklet_obj.tempval = stackless.bomb(AssertionError, msg)
         target._tasklet.tempval = e
 except TaskletExit, e:
     # This doesn't happen with gevent in a worker greenlet, because the
     # exception handler in the hub (gevent.core.__event_handler) stops the
     # TaskletExit from propagating.
     # Still true (but del'ed above): assert greenlet_obj is current
     target = current.parent
     while target.dead:
         target = target.parent
     if target._tasklet is None:
         _first_switch(target, e)
     else:
         target._tasklet.tempval = e
 except:
     # Still true (but del'ed above): assert greenlet_obj is current
     bomb_obj = stackless.bomb(*sys.exc_info())
     target = current.parent
     while True:  # This logic is tested in GreenletTest.testThrow.
         if not target.dead:
             if target._tasklet:
                 break
             # This is tested in greenlet5 of GreenletTest.testSwitchToParent.
             target.dead = True
             target.__dict__.pop('run', None)  # Keep methods of subclasses.
         target = target.parent
     target._tasklet.tempval = bomb_obj
     del bomb_obj  # Save memory.
 if getattr(current, '_is_revived', False):
     current.dead = True
     # Not inserting the placeholder, because the parent wouldn't remove it.
     _insert_after_current_tasklet(target._tasklet)
Example #20
0
 def SendBomb():
   assert c.send(stackless.bomb(typ, val, tb1)) is None
Example #21
0
  def testStackless(self):
    events = []

    def Divide(a, b):
      return a / b

    def Worker(name, c):
      while True:
        events.append(name + '.wait')
        events.append('%s/%s' % (name, c.receive()))

    def Single(name):
      events.append(name + '.single')

    def Cooperative(name):
      while True:
        events.append(name + '.coop')
        stackless.schedule()

    def CooperativeRemove(name):
      while True:
        events.append(name + '.corm')
        stackless.schedule_remove()

    def Run():
      while True:
        events.append('schedule')
        i = len(events)
        stackless.schedule()
        if i == len(events):
          break
      events.append('done')


    c = stackless.channel()

    self.assertTrue(stackless.current is stackless.getmain())
    self.assertTrue(stackless.getcurrent() is stackless.main)
    self.assertEqual(1, stackless.getruncount())
    self.assertTrue(stackless.current is stackless.getcurrent().next)
    self.assertTrue(stackless.current is stackless.getcurrent().prev)
    ta = stackless.tasklet(Worker)('A', c)
    tb = stackless.tasklet(Worker)('B', c)
    tc = stackless.tasklet(Worker)('C', c)
    td = stackless.tasklet().bind(Worker)('D', c)
    self.assertEqual(5, stackless.getruncount())
    self.assertTrue(td is stackless.current.prev)
    self.assertTrue(ta is stackless.getcurrent().next)
    self.assertTrue(td.next is stackless.current)
    self.assertTrue(td.prev is tc)

    self.assertEqual(c.preference, -1)
    self.assertEqual(c.balance, 0)
    del events[:]
    events.append('send')
    self.assertEqual(5, stackless.getruncount())
    self.assertEqual(None, c.send('msg'))
    self.assertEqual(1, stackless.getruncount())
    Run()
    self.assertEqual(' '.join(events), 'send A.wait A/msg A.wait B.wait C.wait D.wait schedule done')

    self.assertEqual(c.preference, -1)
    self.assertEqual(c.balance, -4)
    del events[:]
    events.append('send')
    c.preference = 0  # same as c.preference = 1
    self.assertEqual(1, stackless.getruncount())
    self.assertEqual(None, c.send('msg'))
    self.assertEqual(2, stackless.getruncount())
    Run()
    #print ' '.join(events)
    self.assertEqual(' '.join(events), 'send schedule A/msg A.wait schedule done')

    self.assertEqual(c.preference, 0)
    self.assertEqual(c.balance, -4)
    del events[:]
    c.preference = 1
    events.append('send')
    self.assertEqual(1, stackless.getruncount())
    self.assertEqual(None, c.send('msg'))
    self.assertEqual(2, stackless.getruncount())
    Run()
    self.assertEqual(' '.join(events), 'send schedule B/msg B.wait schedule done')

    self.assertEqual(c.preference, 1)
    del events[:]
    c.preference = 2  # same as c.preference = 1
    events.append('send')
    self.assertEqual(1, stackless.getruncount())
    self.assertEqual(None, c.send('msg'))
    self.assertEqual(None, c.send('msg'))
    self.assertEqual(3, stackless.getruncount())
    Run()
    self.assertEqual(' '.join(events), 'send schedule C/msg C.wait D/msg D.wait schedule done')
    # Now the doubly-linked list is (d, main, a, b, c). Why?

    self.assertEqual(c.balance, -4)
    del events[:]
    c.preference = 5
    events.append('send')
    self.assertEqual(c.balance, -4)
    self.assertEqual(1, stackless.getruncount())
    t = stackless.tasklet(Single)
    self.assertEqual(1, stackless.getruncount())
    self.assertTrue(t is t('T'))
    self.assertEqual(2, stackless.getruncount())
    t.remove()
    self.assertEqual(1, stackless.getruncount())
    self.assertEqual(t, t.insert())
    self.assertEqual(2, stackless.getruncount())
    self.assertEqual(None, c.send('msg1'))
    self.assertEqual(c.balance, -3)
    self.assertEqual(None, c.send('msg2'))
    self.assertEqual(None, c.send('msg3'))
    self.assertEqual(None, c.send('msg4'))
    self.assertEqual(6, stackless.getruncount())
    events.append('a4')
    self.assertEqual(c.balance, 0)
    self.assertEqual(None, c.send('msg5'))
    self.assertEqual(5, stackless.getruncount())
    events.append('a5')
    self.assertEqual(None, c.send('msg6'))
    self.assertEqual(5, stackless.getruncount())
    Run()
    self.assertEqual(' '.join(events), 'send a4 T.single A/msg1 A.wait a5 B/msg2 B.wait schedule C/msg3 C.wait D/msg4 D.wait A/msg5 A.wait B/msg6 B.wait schedule done')

    self.assertTrue(stackless.getcurrent() is stackless.current.next)
    self.assertTrue(stackless.getcurrent() is stackless.current.prev)

    del events[:]
    self.assertEqual(c.balance, -4)
    c.preference = 42
    self.assertEqual(None, c.send('msg1'))
    self.assertEqual(c.balance, -3)
    self.assertTrue(tc is stackless.getcurrent().next)
    self.assertTrue(tc is stackless.current.prev)
    self.assertTrue(tc.prev is stackless.getcurrent())
    self.assertTrue(tc.next is stackless.current)
    self.assertEqual(None, c.send('msg2'))
    self.assertEqual(c.balance, -2)
    self.assertTrue(tc is stackless.getcurrent().next)
    self.assertTrue(td is stackless.current.prev)
    self.assertTrue(td.next is stackless.getcurrent())
    self.assertTrue(td.prev is tc)
    self.assertEqual(None, c.send('msg3'))
    self.assertEqual(c.balance, -1)
    self.assertTrue(tc is stackless.current.next)
    self.assertTrue(ta is stackless.getcurrent().prev)
    self.assertTrue(ta.next is stackless.current)
    self.assertTrue(ta.prev is td)
    self.assertEqual(' '.join(events), '')
    self.assertEqual(4, stackless.getruncount())
    t = stackless.tasklet(Single)('T')
    self.assertTrue(t is stackless.getcurrent().prev)
    self.assertTrue(ta is t.prev)
    self.assertTrue(t.alive)
    self.assertEqual(5, stackless.getruncount())
    t.remove()
    #self.assertTrue(t.next is None  # NotImplementedError in greenstackless)
    self.assertTrue(ta is stackless.current.prev)
    self.assertTrue(t.alive)
    self.assertEqual(4, stackless.getruncount())
    t.run()
    self.assertEqual(4, stackless.getruncount())
    self.assertTrue(not t.alive)
    self.assertEqual(' '.join(events), 'T.single')
    del events[:]
    td.run()
    self.assertEqual(' '.join(events), 'D/msg2 D.wait A/msg3 A.wait')
    del events[:]
    self.assertEqual(c.balance, -3)
    self.assertTrue(tc is stackless.getcurrent().next)
    self.assertTrue(tc is stackless.current.prev)
    self.assertTrue(tc.prev is stackless.getcurrent())
    self.assertTrue(tc.next is stackless.current)
    tc.run()
    self.assertEqual(' '.join(events), 'C/msg1 C.wait')
    del events[:]
    self.assertEqual(c.balance, -4)
    self.assertTrue(stackless.getcurrent() is stackless.current.next)
    self.assertTrue(stackless.getcurrent() is stackless.current.prev)

    t = stackless.tasklet(Cooperative)('T')
    r = stackless.tasklet(CooperativeRemove)('R')
    u = stackless.tasklet(Cooperative)('U')
    self.assertEqual(4, stackless.getruncount())
    del events[:]
    stackless.schedule()
    self.assertEqual(' '.join(events), 'T.coop R.corm U.coop')
    self.assertEqual(3, stackless.getruncount())
    del events[:]
    stackless.schedule()
    self.assertEqual(' '.join(events), 'T.coop U.coop')
    self.assertEqual(3, stackless.getruncount())
    del events[:]
    t.kill()  # This involves t.run(), so u gets run as well. 
    self.assertEqual(' '.join(events), 'U.coop')
    self.assertEqual(2, stackless.getruncount())
    r.kill()
    self.assertEqual(2, stackless.getruncount())
    r.kill()
    self.assertEqual(2, stackless.getruncount())
    u.kill()
    self.assertEqual(1, stackless.getruncount())

    typ, val, tb1 = None, None, None
    try:
      Divide(42, 0)
    except ZeroDivisionError:
      typ, val, tb1 = sys.exc_info()
    self.assertTrue(typ is ZeroDivisionError)

    tb2 = None
    try:
      if hasattr(stackless.getcurrent(), 'throw'):  # greenstackless
        stackless.current.throw(typ, val, tb1)
      else:  # Stackless
        stackless.getcurrent().tempval = stackless.bomb(typ, val, tb1)
        stackless.current.run()
    except:
      self.assertTrue(sys.exc_info()[0] is typ)
      self.assertTrue(sys.exc_info()[1] is val)
      tb2 = sys.exc_info()[2]
      tb3 = tb2 and tb2.tb_next
      tb4 = tb3 and tb3.tb_next
      # greenstackless adds 2 frames.
      self.assertTrue(tb1 in (tb2, tb3, tb4) )
    self.assertTrue(tb2)

    self.assertEqual(-4, c.balance)
    ta.kill()
    self.assertEqual(-3, c.balance)
    td.kill()
    self.assertEqual(-2, c.balance)
    tc.kill()
    self.assertEqual(-1, c.balance)
    tb.kill()
    self.assertEqual(0, c.balance)

    tb2 = None
    self.assertEqual(0, c.balance)
    c.preference = 1
    def SendBomb():
      assert c.send(stackless.bomb(typ, val, tb1)) is None
    stackless.tasklet(SendBomb)()
    try:
      c.receive()
    except:
      self.assertTrue(sys.exc_info()[0] is typ)
      self.assertTrue(sys.exc_info()[1] is val)
      tb2 = sys.exc_info()[2]
      tb3 = tb2 and tb2.tb_next
      tb4 = tb3 and tb3.tb_next
      tb5 = tb4 and tb4.tb_next
      # greenstackless adds 3 frames (including c.receive() etc.)
      self.assertTrue(tb1 in (tb2, tb3, tb4, tb5))
    self.assertTrue(tb2)

    tb2 = None
    self.assertEqual(0, c.balance)
    c.preference = 1
    def SendBomb():
      assert c.send(stackless.bomb(typ, val, tb1)) is None
    stackless.tasklet(SendBomb)()
    try:
      c.receive()
    except:
      self.assertTrue(sys.exc_info()[0] is typ)
      self.assertTrue(sys.exc_info()[1] is val)
      tb2 = sys.exc_info()[2]
      tb3 = tb2 and tb2.tb_next
      tb4 = tb3 and tb3.tb_next
      tb5 = tb4 and tb4.tb_next
      # greenstackless adds 3 frames (including c.receive() etc.)
      self.assertTrue(tb1 in (tb2, tb3, tb4, tb5))
    self.assertTrue(tb2)

    tb2 = None
    def RaiseException(task):
      task.raise_exception(ValueError, 42)
    stackless.tasklet(RaiseException)(stackless.getcurrent())
    try:
      stackless.schedule()
    except:
      self.assertTrue(sys.exc_info()[0] is ValueError)
      self.assertEqual(str(sys.exc_info()[1]), '42')
      tb2 = sys.exc_info()[2]
      # Don't check the traceback (tb2), should be in stackless.schedule().
    self.assertTrue(tb2)

    tb2 = None
    self.assertEqual(0, c.balance)
    c.preference = 1
    def SendException(task):
      assert c.send_exception(ValueError, 43) is None
    stackless.tasklet(SendException)(stackless.current)
    try:
      c.receive()
    except:
      self.assertTrue(sys.exc_info()[0] is ValueError)
      self.assertEqual(str(sys.exc_info()[1]), '43')
      tb2 = sys.exc_info()[2]
      # Don't check the traceback (tb2), should be in stackless.schedule().
    self.assertTrue(tb2)