Пример #1
0
 def __check_and_die(self):
     if not self.ptr:
         # We've been destroyed during the middle of self.run().
         # This method is being called into from C, and it's not
         # safe to go back to C (Windows in particular can abort
         # the process with "GetQueuedCompletionStatusEx: (6) The
         # handle is invalid.") So switch to the parent greenlet.
         getcurrent().parent.throw(LoopExit('Destroyed during run'))
Пример #2
0
    def run(self):
        """
        Entry-point to running the loop. This method is called automatically
        when the hub greenlet is scheduled; do not call it directly.

        :raises gevent.exceptions.LoopExit: If the loop finishes running. This means
           that there are no other scheduled greenlets, and no active
           watchers or servers. In some situations, this indicates a
           programming error.
        """
        assert self is getcurrent(), 'Do not call Hub.run() directly'
        self.start_periodic_monitoring_thread()
        while 1:
            loop = self.loop
            loop.error_handler = self
            try:
                loop.run()
            finally:
                loop.error_handler = None  # break the refcount cycle

            # This function must never return, as it will cause
            # switch() in the parent greenlet to return an unexpected
            # value. This can show up as unexpected failures e.g.,
            # from Waiters raising AssertionError or MulitpleWaiter
            # raising invalid IndexError.
            #
            # It is still possible to kill this greenlet with throw.
            # However, in that case switching to it is no longer safe,
            # as switch will return immediately.
            #
            # Note that there's a problem with simply doing
            # ``self.parent.throw()`` and never actually exiting this
            # greenlet: The greenlet tends to stay alive. This is
            # because throwing the exception captures stack frames
            # (regardless of what we do with the argument) and those
            # get saved. In addition to this object having
            # ``gr_frame`` pointing to this method, which contains
            # ``self``, which points to the parent, and both of which point to
            # an internal thread state dict that points back to the current greenlet for the thread,
            # which is likely to be the parent: a cycle.
            #
            # We can't have ``join()`` tell us to finish, because we
            # need to be able to resume after this throw. The only way
            # to dispose of the greenlet is to use ``self.destroy()``.

            debug = []
            if hasattr(loop, 'debug'):
                debug = loop.debug()
            loop = None

            self.parent.throw(LoopExit('This operation would block forever',
                                       self,
                                       debug))
            # Execution could resume here if another blocking API call is made
            # in the same thread and the hub hasn't been destroyed, so clean
            # up anything left.
            debug = None
Пример #3
0
    def run(self):
        """
        Entry-point to running the loop. This method is called automatically
        when the hub greenlet is scheduled; do not call it directly.

        :raises gevent.exceptions.LoopExit: If the loop finishes running. This means
           that there are no other scheduled greenlets, and no active
           watchers or servers. In some situations, this indicates a
           programming error.
        """
        assert self is getcurrent(), 'Do not call Hub.run() directly'
        self.start_periodic_monitoring_thread()
        while 1:
            loop = self.loop
            loop.error_handler = self
            try:
                loop.run()
            finally:
                loop.error_handler = None  # break the refcount cycle
            debug = []
            if hasattr(loop, 'debug'):
                debug = loop.debug()
            self.parent.throw(LoopExit('This operation would block forever', self, debug))