New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
threading.local doesn't support cyclic garbage collecting #48007
Comments
tp_traverse and tp_clear on threading.local are defined, but the >>> import threading, weakref
>>> o = threading.local()
>>> class X(object): pass
...
>>> x = X()
>>> x.o = o
>>> o.x = x
>>> wr = weakref.ref(x)
>>> del x, o
>>> import gc
>>> gc.collect()
0
>>> wr()
<__main__.X object at 0x9bb0dc4> |
Do you want to fix that? |
This is much more complicated than I thought. The threadstate dict holds a strong reference to each local dict, and therefore the GC will refuse to collect the local dict when there's a cycle. |
This is a patch. It modifies the implementation to use intermediate dummy objects and various weakrefs. This allows to break reference cycles even when the thread state dict is still alive (because it isn't involved in the ref cycles anymore). This also has the benefit of fixing another wart, which is still present in the pure Python implementation, though (see "_threading_local keeps the local of the last stopped thread alive" in test_threading_local). The pure Python implementation should probably be updated, or perhaps removed altogether (since the C version is always compiled anyway). |
Committed in r83918 (py3k), r83919 (3.1) and r83920 (2.7) after Benjamin ok'ed it on IRC. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: