summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2013-08-10 22:30:09 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2013-08-10 22:30:09 (GMT)
commit40322e6ad5f705e294ded37fa4a682f065ec80a2 (patch)
treec5062765b70271c1f449ed65758447276a901347 /Python
parent584e815114b3e1862c510df6a2ccc9d9957eedc0 (diff)
downloadcpython-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.c2
-rw-r--r--Python/pystate.c25
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)
{