mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
bpo-42208: Call GC collect earlier in PyInterpreterState_Clear() (GH-23044)
The last GC collection is now done before clearing builtins and sys dictionaries. Add also assertions to ensure that gc.collect() is no longer called after _PyGC_Fini(). Pass also the tstate to PyInterpreterState_Clear() to pass the correct tstate to _PyGC_CollectNoFail() and _PyGC_Fini().
This commit is contained in:
parent
4fe72090de
commit
eba5bf2f56
4 changed files with 35 additions and 15 deletions
|
@ -268,14 +268,11 @@ out_of_memory:
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
PyInterpreterState_Clear(PyInterpreterState *interp)
|
||||
static void
|
||||
interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate)
|
||||
{
|
||||
_PyRuntimeState *runtime = interp->runtime;
|
||||
|
||||
/* Use the current Python thread state to call audit hooks,
|
||||
not the current Python thread state of 'interp'. */
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
if (_PySys_Audit(tstate, "cpython.PyInterpreterState_Clear", NULL) < 0) {
|
||||
_PyErr_Clear(tstate);
|
||||
}
|
||||
|
@ -306,6 +303,12 @@ PyInterpreterState_Clear(PyInterpreterState *interp)
|
|||
if (_PyRuntimeState_GetFinalizing(runtime) == NULL) {
|
||||
_PyWarnings_Fini(interp);
|
||||
}
|
||||
|
||||
/* Last garbage collection on this interpreter */
|
||||
_PyGC_CollectNoFail(tstate);
|
||||
|
||||
_PyGC_Fini(tstate);
|
||||
|
||||
/* We don't clear sysdict and builtins until the end of this function.
|
||||
Because clearing other attributes can execute arbitrary Python code
|
||||
which requires sysdict and builtins. */
|
||||
|
@ -320,6 +323,25 @@ PyInterpreterState_Clear(PyInterpreterState *interp)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
PyInterpreterState_Clear(PyInterpreterState *interp)
|
||||
{
|
||||
// Use the current Python thread state to call audit hooks and to collect
|
||||
// garbage. It can be different than the current Python thread state
|
||||
// of 'interp'.
|
||||
PyThreadState *current_tstate = _PyThreadState_GET();
|
||||
|
||||
interpreter_clear(interp, current_tstate);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyInterpreterState_Clear(PyThreadState *tstate)
|
||||
{
|
||||
interpreter_clear(tstate->interp, tstate);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
zapthreads(PyInterpreterState *interp, int check_current)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue