From c0fd600454107a608fe78a7ee899054c312bcf89 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 28 Dec 2019 23:51:24 +0100 Subject: [PATCH] stdpy: threading2: join non-daemonic threads at interpreter shutdown Fixes #758 --- direct/src/stdpy/threading2.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/direct/src/stdpy/threading2.py b/direct/src/stdpy/threading2.py index e5c2ab9991..6630bb1738 100644 --- a/direct/src/stdpy/threading2.py +++ b/direct/src/stdpy/threading2.py @@ -14,6 +14,7 @@ module, and so it is therefore layered on top of Panda's thread implementation. """ import sys as _sys +import atexit as _atexit from direct.stdpy import thread as _thread from direct.stdpy.thread import stack_size, _newname, _local as local @@ -395,6 +396,10 @@ class Thread(_Verbose): # operation on/with a NoneType __exc_info = _sys.exc_info + # Set to True when the _shutdown handler is registered as atexit function. + # Protected by _active_limbo_lock. + __registered_atexit = False + def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None, daemon=None): assert group is None, "group argument must be None for now" @@ -439,6 +444,14 @@ class Thread(_Verbose): self._note("%s.start(): starting thread", self) _active_limbo_lock.acquire() _limbo[self] = self + + # If we are starting a non-daemon thread, we need to call join() on it + # when the interpreter exits. Python will call _shutdown() on the + # built-in threading module automatically, but not on our module. + if not self.__daemonic and not Thread.__registered_atexit: + _atexit.register(_shutdown) + Thread.__registered_atexit = True + _active_limbo_lock.release() _start_new_thread(self.__bootstrap, ()) self.__started = True