diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2013-08-10 22:30:09 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2013-08-10 22:30:09 (GMT) |
commit | 40322e6ad5f705e294ded37fa4a682f065ec80a2 (patch) | |
tree | c5062765b70271c1f449ed65758447276a901347 /Python | |
parent | 584e815114b3e1862c510df6a2ccc9d9957eedc0 (diff) | |
download | cpython-40322e6ad5f705e294ded37fa4a682f065ec80a2.zip cpython-40322e6ad5f705e294ded37fa4a682f065ec80a2.tar.gz cpython-40322e6ad5f705e294ded37fa4a682f065ec80a2.tar.bz2 |
Issue #10241: Clear extension module dict copies at interpreter shutdown.
Patch by Neil Schemenauer, minimally modified.
(re-apply after fix for tkinter-related crash)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/import.c | 2 | ||||
-rw-r--r-- | Python/pystate.c | 25 |
2 files changed, 27 insertions, 0 deletions
diff --git a/Python/import.c b/Python/import.c index be73d4b..113123d 100644 --- a/Python/import.c +++ b/Python/import.c @@ -380,6 +380,8 @@ PyImport_Cleanup(void) builtins = interp->builtins; interp->builtins = PyDict_New(); Py_DECREF(builtins); + /* Clear module dict copies stored in the interpreter state */ + _PyState_ClearModules(); /* Collect references */ _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings diff --git a/Python/pystate.c b/Python/pystate.c index 40606bf..924b6a2 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -320,6 +320,31 @@ PyState_RemoveModule(struct PyModuleDef* def) return PyList_SetItem(state->modules_by_index, index, Py_None); } +/* used by import.c:PyImport_Cleanup */ +void +_PyState_ClearModules(void) +{ + PyInterpreterState *state = PyThreadState_GET()->interp; + if (state->modules_by_index) { + Py_ssize_t i; + for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) { + PyObject *m = PyList_GET_ITEM(state->modules_by_index, i); + if (PyModule_Check(m)) { + /* cleanup the saved copy of module dicts */ + PyModuleDef *md = PyModule_GetDef(m); + if (md) + Py_CLEAR(md->m_base.m_copy); + } + } + /* Setting modules_by_index to NULL could be dangerous, so we + clear the list instead. */ + if (PyList_SetSlice(state->modules_by_index, + 0, PyList_GET_SIZE(state->modules_by_index), + NULL)) + PyErr_WriteUnraisable(state->modules_by_index); + } +} + void PyThreadState_Clear(PyThreadState *tstate) { |