@@ -83,24 +83,34 @@ def test_no_stale_references(self):
83
83
# references.
84
84
my_object = MyObject ()
85
85
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 )
89
98
del my_object
90
99
91
100
if Py_GIL_DISABLED :
92
101
# Due to biased reference counting, my_object might only be
93
102
# deallocated while the thread that created it runs -- if the
94
103
# 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
100
112
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 )
104
114
self .assertTrue (collected ,
105
115
"Stale reference not collected within timeout." )
106
116
0 commit comments