bpo-31234: threading_cleanup() now warns immediately (#3138) · python/cpython@ace1ecc

Original file line numberDiff line numberDiff line change

@@ -2030,22 +2030,32 @@ def threading_cleanup(*original_values):

20302030

global environment_altered

20312031
20322032

_MAX_COUNT = 100

2033-

t0 = time.monotonic()

2033+
20342034

for count in range(_MAX_COUNT):

20352035

values = _thread._count(), threading._dangling

20362036

if values == original_values:

20372037

break

2038+
2039+

if not count:

2040+

# Display a warning at the first iteration

2041+

environment_altered = True

2042+

dangling_threads = values[1]

2043+

print("Warning -- threading_cleanup() failed to cleanup "

2044+

"%s threads (count: %s, dangling: %s)"

2045+

% (values[0] - original_values[0],

2046+

values[0], len(dangling_threads)),

2047+

file=sys.stderr)

2048+

for thread in dangling_threads:

2049+

print(f"Dangling thread: {thread!r}", file=sys.stderr)

2050+

sys.stderr.flush()

2051+
2052+

# Don't hold references to threads

2053+

dangling_threads = None

2054+

values = None

2055+
20382056

time.sleep(0.01)

20392057

gc_collect()

2040-

else:

2041-

environment_altered = True

20422058
2043-

dt = time.monotonic() - t0

2044-

print("Warning -- threading_cleanup() failed to cleanup %s threads "

2045-

"after %.0f sec (count: %s, dangling: %s)"

2046-

% (values[0] - original_values[0], dt,

2047-

values[0], len(values[1])),

2048-

file=sys.stderr)

20492059
20502060

def reap_threads(func):

20512061

"""Use this function when threads are being used. This will