Example #1
0
    def destroy(self, destroy_loop=None):
        if self.periodic_monitoring_thread is not None:
            self.periodic_monitoring_thread.kill()
            self.periodic_monitoring_thread = None
        if self._resolver is not None:
            self._resolver.close()
            del self._resolver
        if self._threadpool is not None:
            self._threadpool.kill()
            del self._threadpool
        if destroy_loop is None:
            destroy_loop = not self.loop.default
        if destroy_loop:
            if get_loop() is self.loop:
                # Don't let anyone try to reuse this
                set_loop(None)
            self.loop.destroy()
        else:
            # Store in case another hub is created for this
            # thread.
            set_loop(self.loop)


        self.loop = None
        if _get_hub() is self:
            set_hub(None)
Example #2
0
    def destroy(self, destroy_loop=None):
        """
        Destroy this hub and clean up its resources.

        If you manually create hubs, you *should* call this
        method before disposing of the hub object reference.
        """
        if self.periodic_monitoring_thread is not None:
            self.periodic_monitoring_thread.kill()
            self.periodic_monitoring_thread = None
        if self._resolver is not None:
            self._resolver.close()
            del self._resolver
        if self._threadpool is not None:
            self._threadpool.kill()
            del self._threadpool
        if destroy_loop is None:
            destroy_loop = not self.loop.default
        if destroy_loop:
            if get_loop() is self.loop:
                # Don't let anyone try to reuse this
                set_loop(None)
            self.loop.destroy()
        else:
            # Store in case another hub is created for this
            # thread.
            set_loop(self.loop)

        self.loop = None
        if _get_hub() is self:
            set_hub(None)
Example #3
0
File: hub.py Project: gevent/gevent
    def destroy(self, destroy_loop=None):
        """
        Destroy this hub and clean up its resources.

        If you manually create hubs, you *should* call this
        method before disposing of the hub object reference.
        """
        if self.periodic_monitoring_thread is not None:
            self.periodic_monitoring_thread.kill()
            self.periodic_monitoring_thread = None
        if self._resolver is not None:
            self._resolver.close()
            del self._resolver
        if self._threadpool is not None:
            self._threadpool.kill()
            del self._threadpool
        if destroy_loop is None:
            destroy_loop = not self.loop.default
        if destroy_loop:
            if get_loop() is self.loop:
                # Don't let anyone try to reuse this
                set_loop(None)
            self.loop.destroy()
        else:
            # Store in case another hub is created for this
            # thread.
            set_loop(self.loop)


        self.loop = None
        if _get_hub() is self:
            set_hub(None)
Example #4
0
    def test_destroy_gc(self):
        # Issue 1098: destroying the default loop
        # while using the C extension could crash
        # the interpreter when it exits

        # Create the hub greenlet. This creates one loop
        # object pointing to the default loop.
        gevent.get_hub()

        # Get a new loop object, but using the default
        # C loop
        loop = gevent.config.loop(default=True)
        self.assertTrue(loop.default)
        # Destroy it
        loop.destroy()
        # It no longer claims to be the default
        self.assertFalse(loop.default)

        # Delete it
        del loop
        # Delete the hub. This prompts garbage
        # collection of it and its loop object.
        # (making this test more repeatable; the exit
        # crash only happened when that greenlet object
        # was collected at exit time, which was most common
        # in CPython 3.5)
        from gevent._hub_local import set_hub
        set_hub(None)
Example #5
0
 def _reset_hub(self):
     from gevent._hub_local import set_hub
     from gevent._hub_local import set_loop
     from gevent._hub_local import get_hub_if_exists
     hub = get_hub_if_exists()
     if hub is not None:
         hub.destroy(destroy_loop=True)
     set_hub(None)
     set_loop(None)
Example #6
0
    def destroy(self, destroy_loop=None):
        """
        Destroy this hub and clean up its resources.

        If you manually create hubs, or you use a hub or the gevent
        blocking API from multiple native threads, you *should* call this
        method before disposing of the hub object reference.

        Once this is done, it is impossible to continue running the
        hub. Attempts to use the blocking gevent API with pre-existing
        objects from this native thread and bound to this hub will fail.

        .. versionchanged:: 20.5.1
            Ensure that Python stack frames and greenlets referenced by this
            hub are cleaned up. This guarantees that switching to the hub again
            is not safe after this. (It was never safe, but it's even less safe.)
        """
        if self.periodic_monitoring_thread is not None:
            self.periodic_monitoring_thread.kill()
            self.periodic_monitoring_thread = None
        if self._resolver is not None:
            self._resolver.close()
            del self._resolver
        if self._threadpool is not None:
            self._threadpool.kill()
            del self._threadpool

        # Let the frame be cleaned up by causing the run() function to
        # exit. This is the only way to guarantee that the hub itself
        # and the main greenlet, if this was a secondary thread, get
        # cleaned up. Otherwise there are likely to be reference
        # cycles still around. We MUST do this before we destroy the
        # loop; if we destroy the loop and then switch into the hub,
        # things will go VERY, VERY wrong.
        try:
            self.throw(GreenletExit)
        except LoopExit:
            pass

        if destroy_loop is None:
            destroy_loop = not self.loop.default
        if destroy_loop:
            if get_loop() is self.loop:
                # Don't let anyone try to reuse this
                set_loop(None)
            self.loop.destroy()
        else:
            # Store in case another hub is created for this
            # thread.
            set_loop(self.loop)

        self.loop = None
        if _get_hub() is self:
            set_hub(None)
Example #7
0
    def destroy(self, destroy_loop=None):
        """
        Destroy this hub and clean up its resources.

        If you manually create hubs, or you use a hub or the gevent
        blocking API from multiple native threads, you *should* call this
        method before disposing of the hub object reference. Ideally,
        this should be called from the same thread running the hub, but
        it can be called from other threads after that thread has exited.

        Once this is done, it is impossible to continue running the
        hub. Attempts to use the blocking gevent API with pre-existing
        objects from this native thread and bound to this hub will fail.

        .. versionchanged:: 20.5.1
            Attempt to ensure that Python stack frames and greenlets referenced by this
            hub are cleaned up. This guarantees that switching to the hub again
            is not safe after this. (It was never safe, but it's even less safe.)

            Note that this only works if the hub is destroyed in the same thread it
            is running in. If the hub is destroyed by a different thread
            after a ``fork()``, for example, expect some garbage to leak.
        """
        if destroy_loop is None:
            destroy_loop = not self.loop.default

        if self.periodic_monitoring_thread is not None:
            self.periodic_monitoring_thread.kill()
            self.periodic_monitoring_thread = None
        if self._resolver is not None:
            self._resolver.close()
            del self._resolver
        if self._threadpool is not None:
            self._threadpool.kill()
            del self._threadpool

        # Let the frame be cleaned up by causing the run() function to
        # exit. This is the only way to guarantee that the hub itself
        # and the main greenlet, if this was a secondary thread, get
        # cleaned up. Otherwise there are likely to be reference
        # cycles still around. We MUST do this before we destroy the
        # loop; if we destroy the loop and then switch into the hub,
        # things will go VERY, VERY wrong (because we will have destroyed
        # the C datastructures in the middle of the C function that's
        # using them; the best we can hope for is a segfault).
        try:
            self.throw(HubDestroyed(destroy_loop))
        except LoopExit:
            # Expected.
            pass
        except GreenletError:
            # Must be coming from a different thread.
            # Note that python stack frames are likely to leak
            # in this case.
            pass

        if destroy_loop:
            if get_loop() is self.loop:
                # Don't let anyone try to reuse this
                set_loop(None)
            self.loop.destroy()
        else:
            # Store in case another hub is created for this
            # thread.
            set_loop(self.loop)

        self.loop = None
        if _get_hub() is self:
            set_hub(None)