Skip to content
Draft
2 changes: 1 addition & 1 deletion Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def run(self):

def test_limbo_cleanup(self):
# Issue 7481: Failure to start thread should cleanup the limbo map.
def fail_new_thread(*args):
def fail_new_thread(*args, **kwargs):
raise threading.ThreadError()
_start_new_thread = threading._start_new_thread
threading._start_new_thread = fail_new_thread
Expand Down
13 changes: 12 additions & 1 deletion Lib/threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
except AttributeError:
_CRLock = None
TIMEOUT_MAX = _thread.TIMEOUT_MAX
_wait_for_threads_fini = _thread._wait_for_threads_fini
try:
_internal_after_fork = _thread._after_fork
except AttributeError:
_internal_after_fork = None
del _thread


Expand Down Expand Up @@ -968,7 +973,7 @@ def start(self):
with _active_limbo_lock:
_limbo[self] = self
try:
_start_new_thread(self._bootstrap, ())
_start_new_thread(self._bootstrap, (), daemonic=self._daemonic)
except Exception:
with _active_limbo_lock:
del _limbo[self]
Expand Down Expand Up @@ -1589,6 +1594,7 @@ def _shutdown():
pass

# Join all non-deamon threads
# XXX We should be able to drop this in favor of _wait_for_threads_fini().
while True:
with _shutdown_locks_lock:
locks = list(_shutdown_locks)
Expand All @@ -1605,6 +1611,9 @@ def _shutdown():
# new threads can be spawned while we were waiting for the other
# threads to complete

# Wait for all non-daemon threads to be finalized.
_wait_for_threads_fini()


def main_thread():
"""Return the main thread object.
Expand Down Expand Up @@ -1677,4 +1686,6 @@ def _after_fork():


if hasattr(_os, "register_at_fork"):
if _internal_after_fork is not None:
_os.register_at_fork(after_in_child=_internal_after_fork)
_os.register_at_fork(after_in_child=_after_fork)
Loading