@@ -83,24 +83,34 @@ def test_no_stale_references(self):
8383 # references.
8484 my_object = MyObject ()
8585 my_object_collected = threading .Event ()
86- my_object_callback = weakref .ref (
87- my_object , lambda obj : my_object_collected .set ())
88- fut = self .executor .submit (my_object .my_method )
86+ def set_event ():
87+ if Py_GIL_DISABLED :
88+ # gh-117688 Avoid deadlock by setting the event in a
89+ # background thread. The current thread may be in the middle
90+ # of the my_object_collected.wait() call, which holds locks
91+ # needed by my_object_collected.set().
92+ threading .Thread (target = my_object_collected .set ).start ()
93+ else :
94+ my_object_collected .set ()
95+ my_object_callback = weakref .ref (my_object , lambda obj : set_event ())
96+ # Deliberately discarding the future.
97+ self .executor .submit (my_object .my_method )
8998 del my_object
9099
91100 if Py_GIL_DISABLED :
92101 # Due to biased reference counting, my_object might only be
93102 # deallocated while the thread that created it runs -- if the
94103 # thread is paused waiting on an event, it may not merge the
95- # refcount of the queued object. For that reason, we wait for the
96- # task to finish (so that it's no longer referenced) and force a
97- # GC to ensure that it is collected.
98- fut .result () # Wait for the task to finish.
99- support .gc_collect ()
104+ # refcount of the queued object. For that reason, we alternate
105+ # between running the GC and waiting for the event.
106+ wait_time = 0
107+ collected = False
108+ while not collected and wait_time <= support .SHORT_TIMEOUT :
109+ support .gc_collect ()
110+ collected = my_object_collected .wait (timeout = 1.0 )
111+ wait_time += 1.0
100112 else :
101- del fut # Deliberately discard the future.
102-
103- collected = my_object_collected .wait (timeout = support .SHORT_TIMEOUT )
113+ collected = my_object_collected .wait (timeout = support .SHORT_TIMEOUT )
104114 self .assertTrue (collected ,
105115 "Stale reference not collected within timeout." )
106116
0 commit comments