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

Original file line number Diff line number Diff line change
@@ -2030,22 +2030,32 @@ def threading_cleanup(*original_values):
2030 2030 global environment_altered
2031 2031
2032 2032 _MAX_COUNT = 100
2033 - t0 = time.monotonic()
2033 +
2034 2034 for count in range(_MAX_COUNT):
2035 2035 values = _thread._count(), threading._dangling
2036 2036 if values == original_values:
2037 2037 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 +
2038 2056 time.sleep(0.01)
2039 2057 gc_collect()
2040 -else:
2041 -environment_altered = True
2042 2058
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)
2049 2059
2050 2060 def reap_threads(func):
2051 2061 """Use this function when threads are being used. This will