Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-104341: Fix threading Module Shutdown #104560

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
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