summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2019-11-20 09:38:34 (GMT)
committerGitHub <noreply@github.com>2019-11-20 09:38:34 (GMT)
commit7eee5beaf87be898a679278c480e8dd0df76d351 (patch)
tree166a22474d2ca9a3eab2cddf5de4fd35715e888f
parentb8462477bfd01ff21461065d5063e6b0238ca809 (diff)
downloadcpython-7eee5beaf87be898a679278c480e8dd0df76d351.zip
cpython-7eee5beaf87be898a679278c480e8dd0df76d351.tar.gz
cpython-7eee5beaf87be898a679278c480e8dd0df76d351.tar.bz2
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.
-rw-r--r--Include/internal/pycore_pylifecycle.h4
-rw-r--r--Modules/gcmodule.c4
-rw-r--r--Python/pylifecycle.c128
-rw-r--r--Python/pystate.c4
4 files changed, 82 insertions, 58 deletions
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index f269ffe..b2f2ad8 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -76,7 +76,7 @@ extern void PyOS_FiniInterrupts(void);
extern void _PyExc_Fini(void);
extern void _PyImport_Fini(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 _Py_HashRandomization_Fini(void);
extern void _PyUnicode_Fini(void);
@@ -87,7 +87,7 @@ extern void _PyTraceMalloc_Fini(void);
extern void _PyWarnings_Fini(PyInterpreterState *interp);
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);
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 05ca026..518b054 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -2038,9 +2038,9 @@ _PyGC_DumpShutdownStats(_PyRuntimeState *runtime)
}
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->callbacks);
}
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index edff7f8..2975b3e 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -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
Py_FinalizeEx(void)
{
@@ -1314,56 +1386,9 @@ Py_FinalizeEx(void)
}
#endif /* Py_TRACE_REFS */
- /* Clear interpreter state and all thread states. */
- PyInterpreterState_Clear(interp);
+ finalize_interp_clear(tstate, 1);
- /* Now we decref the exception classes. After this point nothing
- 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);
+ finalize_interp_delete(tstate, 1);
#ifdef Py_TRACE_REFS
/* Display addresses (& refcnts) of all objects still alive.
@@ -1607,9 +1632,8 @@ Py_EndInterpreter(PyThreadState *tstate)
}
_PyImport_Cleanup(tstate);
- PyInterpreterState_Clear(interp);
- PyThreadState_Swap(NULL);
- PyInterpreterState_Delete(interp);
+ finalize_interp_clear(tstate, 0);
+ finalize_interp_delete(tstate, 0);
}
/* Add the __main__ module */
diff --git a/Python/pystate.c b/Python/pystate.c
index 99f93bb..8fff161 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1143,9 +1143,9 @@ _PyGILState_GetInterpreterStateUnsafe(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);
gilstate->autoInterpreterState = NULL;
}