bpo-38858: Factorize Py_EndInterpreter() code (GH-17273)
* Factorize code in common between Py_FinalizeEx() and Py_EndInterpreter(). * Py_EndInterpreter() now also calls _PyWarnings_Fini(). * Call _PyExc_Fini() and _PyGC_Fini() later in the finalization.
This commit is contained in:
parent
b8462477bf
commit
7eee5beaf8
|
@ -76,7 +76,7 @@ extern void PyOS_FiniInterrupts(void);
|
||||||
extern void _PyExc_Fini(void);
|
extern void _PyExc_Fini(void);
|
||||||
extern void _PyImport_Fini(void);
|
extern void _PyImport_Fini(void);
|
||||||
extern void _PyImport_Fini2(void);
|
extern void _PyImport_Fini2(void);
|
||||||
extern void _PyGC_Fini(struct pyruntimestate *runtime);
|
extern void _PyGC_Fini(PyThreadState *tstate);
|
||||||
extern void _PyType_Fini(void);
|
extern void _PyType_Fini(void);
|
||||||
extern void _Py_HashRandomization_Fini(void);
|
extern void _Py_HashRandomization_Fini(void);
|
||||||
extern void _PyUnicode_Fini(void);
|
extern void _PyUnicode_Fini(void);
|
||||||
|
@ -87,7 +87,7 @@ extern void _PyTraceMalloc_Fini(void);
|
||||||
extern void _PyWarnings_Fini(PyInterpreterState *interp);
|
extern void _PyWarnings_Fini(PyInterpreterState *interp);
|
||||||
|
|
||||||
extern void _PyGILState_Init(PyThreadState *tstate);
|
extern void _PyGILState_Init(PyThreadState *tstate);
|
||||||
extern void _PyGILState_Fini(struct pyruntimestate *runtime);
|
extern void _PyGILState_Fini(PyThreadState *tstate);
|
||||||
|
|
||||||
PyAPI_FUNC(void) _PyGC_DumpShutdownStats(struct pyruntimestate *runtime);
|
PyAPI_FUNC(void) _PyGC_DumpShutdownStats(struct pyruntimestate *runtime);
|
||||||
|
|
||||||
|
|
|
@ -2038,9 +2038,9 @@ _PyGC_DumpShutdownStats(_PyRuntimeState *runtime)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_PyGC_Fini(_PyRuntimeState *runtime)
|
_PyGC_Fini(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
struct _gc_runtime_state *state = &runtime->gc;
|
struct _gc_runtime_state *state = &tstate->interp->runtime->gc;
|
||||||
Py_CLEAR(state->garbage);
|
Py_CLEAR(state->garbage);
|
||||||
Py_CLEAR(state->callbacks);
|
Py_CLEAR(state->callbacks);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1161,6 +1161,78 @@ flush_std_files(void)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
finalize_interp_types(PyThreadState *tstate, int is_main_interp)
|
||||||
|
{
|
||||||
|
if (is_main_interp) {
|
||||||
|
/* Sundry finalizers */
|
||||||
|
_PyMethod_Fini();
|
||||||
|
_PyFrame_Fini();
|
||||||
|
_PyCFunction_Fini();
|
||||||
|
_PyTuple_Fini();
|
||||||
|
_PyList_Fini();
|
||||||
|
_PySet_Fini();
|
||||||
|
_PyBytes_Fini();
|
||||||
|
_PyLong_Fini();
|
||||||
|
_PyFloat_Fini();
|
||||||
|
_PyDict_Fini();
|
||||||
|
_PySlice_Fini();
|
||||||
|
}
|
||||||
|
|
||||||
|
_PyWarnings_Fini(tstate->interp);
|
||||||
|
|
||||||
|
if (is_main_interp) {
|
||||||
|
_Py_HashRandomization_Fini();
|
||||||
|
_PyArg_Fini();
|
||||||
|
_PyAsyncGen_Fini();
|
||||||
|
_PyContext_Fini();
|
||||||
|
|
||||||
|
/* Cleanup Unicode implementation */
|
||||||
|
_PyUnicode_Fini();
|
||||||
|
_Py_ClearFileSystemEncoding();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
finalize_interp_clear(PyThreadState *tstate, int is_main_interp)
|
||||||
|
{
|
||||||
|
/* Clear interpreter state and all thread states */
|
||||||
|
PyInterpreterState_Clear(tstate->interp);
|
||||||
|
|
||||||
|
finalize_interp_types(tstate, is_main_interp);
|
||||||
|
|
||||||
|
if (is_main_interp) {
|
||||||
|
/* XXX Still allocated:
|
||||||
|
- various static ad-hoc pointers to interned strings
|
||||||
|
- int and float free list blocks
|
||||||
|
- whatever various modules and libraries allocate
|
||||||
|
*/
|
||||||
|
|
||||||
|
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
|
||||||
|
|
||||||
|
_PyExc_Fini();
|
||||||
|
_PyGC_Fini(tstate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
finalize_interp_delete(PyThreadState *tstate, int is_main_interp)
|
||||||
|
{
|
||||||
|
if (is_main_interp) {
|
||||||
|
/* Cleanup auto-thread-state */
|
||||||
|
_PyGILState_Fini(tstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete current thread. After this, many C API calls become crashy. */
|
||||||
|
PyThreadState_Swap(NULL);
|
||||||
|
|
||||||
|
PyInterpreterState_Delete(tstate->interp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
Py_FinalizeEx(void)
|
Py_FinalizeEx(void)
|
||||||
{
|
{
|
||||||
|
@ -1314,56 +1386,9 @@ Py_FinalizeEx(void)
|
||||||
}
|
}
|
||||||
#endif /* Py_TRACE_REFS */
|
#endif /* Py_TRACE_REFS */
|
||||||
|
|
||||||
/* Clear interpreter state and all thread states. */
|
finalize_interp_clear(tstate, 1);
|
||||||
PyInterpreterState_Clear(interp);
|
|
||||||
|
|
||||||
/* Now we decref the exception classes. After this point nothing
|
finalize_interp_delete(tstate, 1);
|
||||||
can raise an exception. That's okay, because each Fini() method
|
|
||||||
below has been checked to make sure no exceptions are ever
|
|
||||||
raised.
|
|
||||||
*/
|
|
||||||
|
|
||||||
_PyExc_Fini();
|
|
||||||
|
|
||||||
/* Sundry finalizers */
|
|
||||||
_PyMethod_Fini();
|
|
||||||
_PyFrame_Fini();
|
|
||||||
_PyCFunction_Fini();
|
|
||||||
_PyTuple_Fini();
|
|
||||||
_PyList_Fini();
|
|
||||||
_PySet_Fini();
|
|
||||||
_PyBytes_Fini();
|
|
||||||
_PyLong_Fini();
|
|
||||||
_PyFloat_Fini();
|
|
||||||
_PyDict_Fini();
|
|
||||||
_PySlice_Fini();
|
|
||||||
_PyGC_Fini(runtime);
|
|
||||||
_PyWarnings_Fini(interp);
|
|
||||||
_Py_HashRandomization_Fini();
|
|
||||||
_PyArg_Fini();
|
|
||||||
_PyAsyncGen_Fini();
|
|
||||||
_PyContext_Fini();
|
|
||||||
|
|
||||||
/* Cleanup Unicode implementation */
|
|
||||||
_PyUnicode_Fini();
|
|
||||||
|
|
||||||
_Py_ClearFileSystemEncoding();
|
|
||||||
|
|
||||||
/* XXX Still allocated:
|
|
||||||
- various static ad-hoc pointers to interned strings
|
|
||||||
- int and float free list blocks
|
|
||||||
- whatever various modules and libraries allocate
|
|
||||||
*/
|
|
||||||
|
|
||||||
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
|
|
||||||
|
|
||||||
/* Cleanup auto-thread-state */
|
|
||||||
_PyGILState_Fini(runtime);
|
|
||||||
|
|
||||||
/* Delete current thread. After this, many C API calls become crashy. */
|
|
||||||
PyThreadState_Swap(NULL);
|
|
||||||
|
|
||||||
PyInterpreterState_Delete(interp);
|
|
||||||
|
|
||||||
#ifdef Py_TRACE_REFS
|
#ifdef Py_TRACE_REFS
|
||||||
/* Display addresses (& refcnts) of all objects still alive.
|
/* Display addresses (& refcnts) of all objects still alive.
|
||||||
|
@ -1607,9 +1632,8 @@ Py_EndInterpreter(PyThreadState *tstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
_PyImport_Cleanup(tstate);
|
_PyImport_Cleanup(tstate);
|
||||||
PyInterpreterState_Clear(interp);
|
finalize_interp_clear(tstate, 0);
|
||||||
PyThreadState_Swap(NULL);
|
finalize_interp_delete(tstate, 0);
|
||||||
PyInterpreterState_Delete(interp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the __main__ module */
|
/* Add the __main__ module */
|
||||||
|
|
|
@ -1143,9 +1143,9 @@ _PyGILState_GetInterpreterStateUnsafe(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_PyGILState_Fini(_PyRuntimeState *runtime)
|
_PyGILState_Fini(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
|
struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
|
||||||
PyThread_tss_delete(&gilstate->autoTSSkey);
|
PyThread_tss_delete(&gilstate->autoTSSkey);
|
||||||
gilstate->autoInterpreterState = NULL;
|
gilstate->autoInterpreterState = NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue