Issue #10241: Clear extension module dict copies at interpreter shutdown.

Patch by Neil Schemenauer, minimally modified.

(re-apply after fix for tkinter-related crash)
This commit is contained in:
Antoine Pitrou 2013-08-11 00:30:09 +02:00
parent 584e815114
commit 40322e6ad5
4 changed files with 33 additions and 0 deletions

View File

@ -134,6 +134,9 @@ PyAPI_FUNC(int) PyState_AddModule(PyObject*, struct PyModuleDef*);
PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*);
#endif
PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*);
#ifndef Py_LIMITED_API
PyAPI_FUNC(void) _PyState_ClearModules(void);
#endif
PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *);
PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);

View File

@ -54,6 +54,9 @@ Core and Builtins
- Issue #17899: Fix rare file descriptor leak in os.listdir().
- Issue #10241: Clear extension module dict copies at interpreter shutdown.
Patch by Neil Schemenauer, minimally modified.
- Issue #9035: ismount now recognises volumes mounted below a drive root
on Windows. Original patch by Atsuo Ishimoto.

View File

@ -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

View File

@ -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)
{