-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
Closed
Labels
Description
In #114824, I modified test_no_stale_references
so that it passes in the --disable-gil
build. Unfortunately, that change was not sufficient and the test may still hang once the GIL is actually disabled.
Relevant code:
cpython/Lib/test/test_concurrent_futures/executor.py
Lines 84 to 87 in a25c02e
my_object = MyObject() | |
my_object_collected = threading.Event() | |
my_object_callback = weakref.ref( | |
my_object, lambda obj: my_object_collected.set()) |
collected = my_object_collected.wait(timeout=support.SHORT_TIMEOUT) |
The problem is due to the combination of two issues:
- Due to biased reference counting, the destructor for
my_object
is usually called on the main thread asynchronously (by the eval breaker logic) - The destructor may be called somewhere in the implementation of
my_object_collected.wait()
. Themy_object_collected.wait()
implementation holds some of the same locks thatmy_object_collected.set()
also needs. This can lead to deadlock if the timing is unlucky: themy_object_collected.set()
call from the weakref callback tries to acquire locks already held by the current thread and deadlocks.