Skip to content

Commit 159e9b3

Browse files
vstinnershihai1991
authored andcommitted
bpo-38858: Factorize Py_EndInterpreter() code (pythonGH-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.
1 parent 52ac04a commit 159e9b3

File tree

4 files changed

+82
-58
lines changed

4 files changed

+82
-58
lines changed

Include/internal/pycore_pylifecycle.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ extern void PyOS_FiniInterrupts(void);
7676
extern void _PyExc_Fini(void);
7777
extern void _PyImport_Fini(void);
7878
extern void _PyImport_Fini2(void);
79-
extern void _PyGC_Fini(struct pyruntimestate *runtime);
79+
extern void _PyGC_Fini(PyThreadState *tstate);
8080
extern void _PyType_Fini(void);
8181
extern void _Py_HashRandomization_Fini(void);
8282
extern void _PyUnicode_Fini(void);
@@ -87,7 +87,7 @@ extern void _PyTraceMalloc_Fini(void);
8787
extern void _PyWarnings_Fini(PyInterpreterState *interp);
8888

8989
extern void _PyGILState_Init(PyThreadState *tstate);
90-
extern void _PyGILState_Fini(struct pyruntimestate *runtime);
90+
extern void _PyGILState_Fini(PyThreadState *tstate);
9191

9292
PyAPI_FUNC(void) _PyGC_DumpShutdownStats(struct pyruntimestate *runtime);
9393

Modules/gcmodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,9 +2038,9 @@ _PyGC_DumpShutdownStats(_PyRuntimeState *runtime)
20382038
}
20392039

20402040
void
2041-
_PyGC_Fini(_PyRuntimeState *runtime)
2041+
_PyGC_Fini(PyThreadState *tstate)
20422042
{
2043-
struct _gc_runtime_state *state = &runtime->gc;
2043+
struct _gc_runtime_state *state = &tstate->interp->runtime->gc;
20442044
Py_CLEAR(state->garbage);
20452045
Py_CLEAR(state->callbacks);
20462046
}

Python/pylifecycle.c

Lines changed: 76 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,78 @@ flush_std_files(void)
11611161
11621162
*/
11631163

1164+
1165+
static void
1166+
finalize_interp_types(PyThreadState *tstate, int is_main_interp)
1167+
{
1168+
if (is_main_interp) {
1169+
/* Sundry finalizers */
1170+
_PyMethod_Fini();
1171+
_PyFrame_Fini();
1172+
_PyCFunction_Fini();
1173+
_PyTuple_Fini();
1174+
_PyList_Fini();
1175+
_PySet_Fini();
1176+
_PyBytes_Fini();
1177+
_PyLong_Fini();
1178+
_PyFloat_Fini();
1179+
_PyDict_Fini();
1180+
_PySlice_Fini();
1181+
}
1182+
1183+
_PyWarnings_Fini(tstate->interp);
1184+
1185+
if (is_main_interp) {
1186+
_Py_HashRandomization_Fini();
1187+
_PyArg_Fini();
1188+
_PyAsyncGen_Fini();
1189+
_PyContext_Fini();
1190+
1191+
/* Cleanup Unicode implementation */
1192+
_PyUnicode_Fini();
1193+
_Py_ClearFileSystemEncoding();
1194+
}
1195+
}
1196+
1197+
1198+
static void
1199+
finalize_interp_clear(PyThreadState *tstate, int is_main_interp)
1200+
{
1201+
/* Clear interpreter state and all thread states */
1202+
PyInterpreterState_Clear(tstate->interp);
1203+
1204+
finalize_interp_types(tstate, is_main_interp);
1205+
1206+
if (is_main_interp) {
1207+
/* XXX Still allocated:
1208+
- various static ad-hoc pointers to interned strings
1209+
- int and float free list blocks
1210+
- whatever various modules and libraries allocate
1211+
*/
1212+
1213+
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
1214+
1215+
_PyExc_Fini();
1216+
_PyGC_Fini(tstate);
1217+
}
1218+
}
1219+
1220+
1221+
static void
1222+
finalize_interp_delete(PyThreadState *tstate, int is_main_interp)
1223+
{
1224+
if (is_main_interp) {
1225+
/* Cleanup auto-thread-state */
1226+
_PyGILState_Fini(tstate);
1227+
}
1228+
1229+
/* Delete current thread. After this, many C API calls become crashy. */
1230+
PyThreadState_Swap(NULL);
1231+
1232+
PyInterpreterState_Delete(tstate->interp);
1233+
}
1234+
1235+
11641236
int
11651237
Py_FinalizeEx(void)
11661238
{
@@ -1314,56 +1386,9 @@ Py_FinalizeEx(void)
13141386
}
13151387
#endif /* Py_TRACE_REFS */
13161388

1317-
/* Clear interpreter state and all thread states. */
1318-
PyInterpreterState_Clear(interp);
1389+
finalize_interp_clear(tstate, 1);
13191390

1320-
/* Now we decref the exception classes. After this point nothing
1321-
can raise an exception. That's okay, because each Fini() method
1322-
below has been checked to make sure no exceptions are ever
1323-
raised.
1324-
*/
1325-
1326-
_PyExc_Fini();
1327-
1328-
/* Sundry finalizers */
1329-
_PyMethod_Fini();
1330-
_PyFrame_Fini();
1331-
_PyCFunction_Fini();
1332-
_PyTuple_Fini();
1333-
_PyList_Fini();
1334-
_PySet_Fini();
1335-
_PyBytes_Fini();
1336-
_PyLong_Fini();
1337-
_PyFloat_Fini();
1338-
_PyDict_Fini();
1339-
_PySlice_Fini();
1340-
_PyGC_Fini(runtime);
1341-
_PyWarnings_Fini(interp);
1342-
_Py_HashRandomization_Fini();
1343-
_PyArg_Fini();
1344-
_PyAsyncGen_Fini();
1345-
_PyContext_Fini();
1346-
1347-
/* Cleanup Unicode implementation */
1348-
_PyUnicode_Fini();
1349-
1350-
_Py_ClearFileSystemEncoding();
1351-
1352-
/* XXX Still allocated:
1353-
- various static ad-hoc pointers to interned strings
1354-
- int and float free list blocks
1355-
- whatever various modules and libraries allocate
1356-
*/
1357-
1358-
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
1359-
1360-
/* Cleanup auto-thread-state */
1361-
_PyGILState_Fini(runtime);
1362-
1363-
/* Delete current thread. After this, many C API calls become crashy. */
1364-
PyThreadState_Swap(NULL);
1365-
1366-
PyInterpreterState_Delete(interp);
1391+
finalize_interp_delete(tstate, 1);
13671392

13681393
#ifdef Py_TRACE_REFS
13691394
/* Display addresses (& refcnts) of all objects still alive.
@@ -1607,9 +1632,8 @@ Py_EndInterpreter(PyThreadState *tstate)
16071632
}
16081633

16091634
_PyImport_Cleanup(tstate);
1610-
PyInterpreterState_Clear(interp);
1611-
PyThreadState_Swap(NULL);
1612-
PyInterpreterState_Delete(interp);
1635+
finalize_interp_clear(tstate, 0);
1636+
finalize_interp_delete(tstate, 0);
16131637
}
16141638

16151639
/* Add the __main__ module */

Python/pystate.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,9 +1143,9 @@ _PyGILState_GetInterpreterStateUnsafe(void)
11431143
}
11441144

11451145
void
1146-
_PyGILState_Fini(_PyRuntimeState *runtime)
1146+
_PyGILState_Fini(PyThreadState *tstate)
11471147
{
1148-
struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
1148+
struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
11491149
PyThread_tss_delete(&gilstate->autoTSSkey);
11501150
gilstate->autoInterpreterState = NULL;
11511151
}

0 commit comments

Comments
 (0)