Skip to content

Commit 09c0d2a

Browse files
committed
gh-151518: Simplify the GC fairness regression
Use explicit warmup imports and a joined non-daemon collector. Run the child through script_helper with a faulthandler watchdog so a stalled attachment still fails with a traceback. Describe the bug as a fairness issue in the NEWS entry.
1 parent d2adaf4 commit 09c0d2a

2 files changed

Lines changed: 28 additions & 29 deletions

File tree

‎Lib/test/test_free_threading/test_gc.py‎

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import unittest
22

3-
import subprocess
4-
import sys
53
import textwrap
64
import threading
75
from threading import Thread
@@ -11,7 +9,7 @@
119
import weakref
1210

1311
from test import support
14-
from test.support import threading_helper
12+
from test.support import script_helper, threading_helper
1513

1614

1715
class MyObj:
@@ -214,20 +212,32 @@ def reader():
214212

215213
@support.requires_subprocess()
216214
def test_tight_gc_loop_does_not_starve_attach(self):
217-
script = textwrap.dedent("""
215+
script = textwrap.dedent(f"""
216+
import faulthandler
217+
218+
faulthandler.dump_traceback_later({support.SHORT_TIMEOUT}, exit=True)
219+
218220
import gc
219-
import importlib
220221
import threading
221222
import time
222223
223-
modules = (
224-
"abc", "argparse", "collections", "contextlib",
225-
"decimal", "enum", "functools", "heapq",
226-
"importlib", "inspect", "itertools", "json",
227-
"math", "operator", "random", "re",
228-
)
229-
for name in modules:
230-
importlib.import_module(name)
224+
# Add GC-tracked objects to lengthen the stop-the-world pauses.
225+
import abc
226+
import argparse
227+
import collections
228+
import contextlib
229+
import decimal
230+
import enum
231+
import functools
232+
import heapq
233+
import importlib
234+
import inspect
235+
import itertools
236+
import json
237+
import math
238+
import operator
239+
import random
240+
import re
231241
232242
started = threading.Event()
233243
stop = threading.Event()
@@ -238,28 +248,17 @@ def collect():
238248
while not stop.is_set():
239249
gc.collect()
240250
241-
thread = threading.Thread(target=collect, daemon=True)
251+
thread = threading.Thread(target=collect)
242252
thread.start()
243253
started.wait()
244254
# Each reattachment must make progress between consecutive pauses.
245255
for _ in range(50):
246256
time.sleep(0.02)
247257
stop.set()
248258
thread.join()
259+
faulthandler.cancel_dump_traceback_later()
249260
""")
250-
proc = subprocess.run(
251-
[sys.executable, "-I", "-X", "gil=0", "-X", "faulthandler",
252-
"-c", script],
253-
stdout=subprocess.PIPE,
254-
stderr=subprocess.PIPE,
255-
text=True,
256-
timeout=support.SHORT_TIMEOUT,
257-
)
258-
self.assertEqual(
259-
proc.returncode,
260-
0,
261-
f"stdout:\n{proc.stdout}\nstderr:\n{proc.stderr}",
262-
)
261+
script_helper.assert_python_ok("-X", "gil=0", "-c", script)
263262

264263

265264
if __name__ == "__main__":
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Fix a free-threaded stop-the-world race that could starve a thread reattaching
2-
after being suspended while detached.
1+
Fix a free-threaded stop-the-world fairness issue that could starve a thread
2+
reattaching after being suspended while detached.

0 commit comments

Comments
 (0)