Skip to content

Commit b9f0061

Browse files
add news and test
1 parent 17efa94 commit b9f0061

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

‎Lib/test/test_free_threading/test_gc.py‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import time
66
from unittest import TestCase
77
import gc
8+
import weakref
89

10+
from test import support
911
from test.support import threading_helper
1012

1113

@@ -95,6 +97,39 @@ def evil():
9597
thread.start()
9698
thread.join()
9799

100+
def test_merge_brc_queue_of_detached_thread(self):
101+
# GH-157838: objects queued for merging by a thread that is detached
102+
# (blocked in a lock acquire, sleep, etc.) are merged and freed on its
103+
# behalf instead of staying alive until it runs Python code again.
104+
lock = threading.Lock()
105+
lock.acquire()
106+
ready = threading.Event()
107+
objs = []
108+
109+
def worker():
110+
# Objects owned by this thread; only the list holds a reference.
111+
objs.extend(MyObj() for _ in range(100))
112+
ready.set()
113+
lock.acquire() # block while detached
114+
115+
thread = Thread(target=worker)
116+
thread.start()
117+
try:
118+
ready.wait()
119+
# The worker may not have detached yet when the first objects
120+
# are dropped; keep trying until one is freed immediately.
121+
for _ in support.sleeping_retry(support.SHORT_TIMEOUT, error=False):
122+
obj = objs.pop()
123+
wr = weakref.ref(obj)
124+
del obj
125+
if wr() is None:
126+
break
127+
else:
128+
self.fail("object not freed while owning thread was detached")
129+
finally:
130+
lock.release()
131+
thread.join()
132+
98133
def test_gc_callbacks_race_with_mutation(self):
99134
def collect():
100135
b.wait()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Merge biased reference counts on behalf of threads that are detached instead of waiting for them to attach again, in the free-threaded build.

0 commit comments

Comments
 (0)