Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-38858: Factorize Py_EndInterpreter() code #17273

Merged
merged 1 commit into from Nov 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions Include/internal/pycore_pylifecycle.h
Expand Up @@ -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);
Expand All @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions Modules/gcmodule.c
Expand Up @@ -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);
}
Expand Down
128 changes: 76 additions & 52 deletions Python/pylifecycle.c
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 */
Expand Down
4 changes: 2 additions & 2 deletions Python/pystate.c
Expand Up @@ -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;
}
Expand Down