Skip to content

Commit 3a368a6

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 26c9cb0 commit 3a368a6

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
@@ -10,7 +8,7 @@
108
import gc
119

1210
from test import support
13-
from test.support import threading_helper
11+
from test.support import script_helper, threading_helper
1412

1513

1614
class MyObj:
@@ -180,20 +178,32 @@ def reader():
180178

181179
@support.requires_subprocess()
182180
def test_tight_gc_loop_does_not_starve_attach(self):
183-
script = textwrap.dedent("""
181+
script = textwrap.dedent(f"""
182+
import faulthandler
183+
184+
faulthandler.dump_traceback_later({support.SHORT_TIMEOUT}, exit=True)
185+
184186
import gc
185-
import importlib
186187
import threading
187188
import time
188189
189-
modules = (
190-
"abc", "argparse", "collections", "contextlib",
191-
"decimal", "enum", "functools", "heapq",
192-
"importlib", "inspect", "itertools", "json",
193-
"math", "operator", "random", "re",
194-
)
195-
for name in modules:
196-
importlib.import_module(name)
190+
# Add GC-tracked objects to lengthen the stop-the-world pauses.
191+
import abc
192+
import argparse
193+
import collections
194+
import contextlib
195+
import decimal
196+
import enum
197+
import functools
198+
import heapq
199+
import importlib
200+
import inspect
201+
import itertools
202+
import json
203+
import math
204+
import operator
205+
import random
206+
import re
197207
198208
started = threading.Event()
199209
stop = threading.Event()
@@ -204,28 +214,17 @@ def collect():
204214
while not stop.is_set():
205215
gc.collect()
206216
207-
thread = threading.Thread(target=collect, daemon=True)
217+
thread = threading.Thread(target=collect)
208218
thread.start()
209219
started.wait()
210220
# Each reattachment must make progress between consecutive pauses.
211221
for _ in range(50):
212222
time.sleep(0.02)
213223
stop.set()
214224
thread.join()
225+
faulthandler.cancel_dump_traceback_later()
215226
""")
216-
proc = subprocess.run(
217-
[sys.executable, "-I", "-X", "gil=0", "-X", "faulthandler",
218-
"-c", script],
219-
stdout=subprocess.PIPE,
220-
stderr=subprocess.PIPE,
221-
text=True,
222-
timeout=support.SHORT_TIMEOUT,
223-
)
224-
self.assertEqual(
225-
proc.returncode,
226-
0,
227-
f"stdout:\n{proc.stdout}\nstderr:\n{proc.stderr}",
228-
)
227+
script_helper.assert_python_ok("-X", "gil=0", "-c", script)
229228

230229

231230
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)