Skip to content

Conversation

@vstinner
Copy link
Member

@vstinnervstinner commented Dec 16, 2020

Port the _thread extension module to the multiphase initialization
API (PEP 489) and convert its static types to heap types.

https://bugs.python.org/issue1635741

Port the _thread extension module to the multiphase initialization API (PEP 489) and convert its static types to heap types.
@vstinner
Copy link
MemberAuthor

Sadly, the following test leaks:

 def test_leak(self): code = textwrap.dedent(r""" import os import _thread lock = _thread.allocate_lock() def _after_fork(): pass os.register_at_fork(after_in_child=_after_fork) """) test.support.run_in_subinterp(code) 

Output:

$ ./python -m test test_threading -R 3:3 -m test_leak 0:00:00 load avg: 0.77 Run tests sequentially 0:00:00 load avg: 0.77 [1/1] test_threading beginning 6 repetitions 123456 ...... test_threading leaked [56, 56, 56] references, sum=168 test_threading leaked [21, 21, 21] memory blocks, sum=63 test_threading failed == Tests result: FAILURE == 1 test failed: test_threading Total duration: 724 ms Tests result: FAILURE 

I will investigate later why it leaks.

@vstinnervstinner changed the title bpo-1635741: Port _thread to multiphase init[WIP] bpo-1635741: Port _thread to multiphase initDec 16, 2020
@vstinner
Copy link
MemberAuthor

Workaround for the leak:

diff --git a/Python/pystate.c b/Python/pystate.c index ead25b08d7..66ad5d6514 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -311,6 +311,7 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) /* Last garbage collection on this interpreter */ _PyGC_CollectNoFail(tstate); + _PyGC_CollectNoFail(tstate); _PyGC_Fini(tstate); /* We don't clear sysdict and builtins until the end of this function. 

@vstinner
Copy link
MemberAuthor

Example of leaking tests:

./python -m test test_threading -R 3:3 -m test_threads_join -m test_threads_join_2 

These tests run import threading in a subinterpreter, and Lib/threading.py calls os.register_at_fork() which keeps the threading module dictionary alive longer than expected: I created https://bugs.python.org/issue42671 to try to fix this issue.

@vstinnervstinner changed the title [WIP] bpo-1635741: Port _thread to multiphase initbpo-1635741: Port _thread to multiphase initDec 18, 2020
@vstinnervstinner marked this pull request as ready for review December 18, 2020 00:21
@vstinner
Copy link
MemberAuthor

I fixed the leak by adding a traverse function to the lock type (and convert it to a GC type).

@vstinnervstinner merged commit 6104013 into python:masterDec 18, 2020
@vstinnervstinner deleted the thread_state branch December 18, 2020 00:39
adorilson pushed a commit to adorilson/cpython that referenced this pull request Mar 13, 2021
Port the _thread extension module to the multiphase initialization API (PEP 489) and convert its static types to heap types. Add a traverse function to the lock type, so the garbage collector can break reference cycles.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@vstinner@the-knights-who-say-ni@bedevere-bot