mirror of
https://github.com/python/cpython.git
synced 2025-10-06 15:11:58 +00:00
bpo-39812: Remove daemon threads in concurrent.futures (GH-19149)
Remove daemon threads from :mod:`concurrent.futures` by adding an internal `threading._register_atexit()`, which calls registered functions prior to joining all non-daemon threads. This allows for compatibility with subinterpreters, which don't support daemon threads.
This commit is contained in:
parent
5f9c131c09
commit
b61b818d91
6 changed files with 99 additions and 32 deletions
|
@ -3,6 +3,7 @@
|
|||
import os as _os
|
||||
import sys as _sys
|
||||
import _thread
|
||||
import functools
|
||||
|
||||
from time import monotonic as _time
|
||||
from _weakrefset import WeakSet
|
||||
|
@ -1346,6 +1347,27 @@ def enumerate():
|
|||
with _active_limbo_lock:
|
||||
return list(_active.values()) + list(_limbo.values())
|
||||
|
||||
|
||||
_threading_atexits = []
|
||||
_SHUTTING_DOWN = False
|
||||
|
||||
def _register_atexit(func, *arg, **kwargs):
|
||||
"""CPython internal: register *func* to be called before joining threads.
|
||||
|
||||
The registered *func* is called with its arguments just before all
|
||||
non-daemon threads are joined in `_shutdown()`. It provides a similar
|
||||
purpose to `atexit.register()`, but its functions are called prior to
|
||||
threading shutdown instead of interpreter shutdown.
|
||||
|
||||
For similarity to atexit, the registered functions are called in reverse.
|
||||
"""
|
||||
if _SHUTTING_DOWN:
|
||||
raise RuntimeError("can't register atexit after shutdown")
|
||||
|
||||
call = functools.partial(func, *arg, **kwargs)
|
||||
_threading_atexits.append(call)
|
||||
|
||||
|
||||
from _thread import stack_size
|
||||
|
||||
# Create the main thread object,
|
||||
|
@ -1367,6 +1389,8 @@ def _shutdown():
|
|||
# _shutdown() was already called
|
||||
return
|
||||
|
||||
global _SHUTTING_DOWN
|
||||
_SHUTTING_DOWN = True
|
||||
# Main thread
|
||||
tlock = _main_thread._tstate_lock
|
||||
# The main thread isn't finished yet, so its thread state lock can't have
|
||||
|
@ -1376,6 +1400,11 @@ def _shutdown():
|
|||
tlock.release()
|
||||
_main_thread._stop()
|
||||
|
||||
# Call registered threading atexit functions before threads are joined.
|
||||
# Order is reversed, similar to atexit.
|
||||
for atexit_call in reversed(_threading_atexits):
|
||||
atexit_call()
|
||||
|
||||
# Join all non-deamon threads
|
||||
while True:
|
||||
with _shutdown_locks_lock:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue