Commit aacbd5cf authored by Neil Schemenauer's avatar Neil Schemenauer

Add garbage collection for module objects. Closes patch #102939 and

fixes bug #126345.
parent 5d3c7f73
...@@ -18,6 +18,7 @@ PyModule_New(char *name) ...@@ -18,6 +18,7 @@ PyModule_New(char *name)
return NULL; return NULL;
nameobj = PyString_FromString(name); nameobj = PyString_FromString(name);
m->md_dict = PyDict_New(); m->md_dict = PyDict_New();
PyObject_GC_Init(m);
if (m->md_dict == NULL || nameobj == NULL) if (m->md_dict == NULL || nameobj == NULL)
goto fail; goto fail;
if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0) if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0)
...@@ -130,11 +131,12 @@ _PyModule_Clear(PyObject *m) ...@@ -130,11 +131,12 @@ _PyModule_Clear(PyObject *m)
static void static void
module_dealloc(PyModuleObject *m) module_dealloc(PyModuleObject *m)
{ {
PyObject_GC_Fini(m);
if (m->md_dict != NULL) { if (m->md_dict != NULL) {
_PyModule_Clear((PyObject *)m); _PyModule_Clear((PyObject *)m);
Py_DECREF(m->md_dict); Py_DECREF(m->md_dict);
} }
PyObject_DEL(m); PyObject_DEL(PyObject_AS_GC(m));
} }
static PyObject * static PyObject *
...@@ -211,11 +213,22 @@ module_setattr(PyModuleObject *m, char *name, PyObject *v) ...@@ -211,11 +213,22 @@ module_setattr(PyModuleObject *m, char *name, PyObject *v)
return PyDict_SetItemString(m->md_dict, name, v); return PyDict_SetItemString(m->md_dict, name, v);
} }
/* We only need a traverse function, no clear function: If the module
is in a cycle, md_dict will be cleared as well, which will break
the cycle. */
static int
module_traverse(PyModuleObject *m, visitproc visit, void *arg)
{
if (m->md_dict != NULL)
return visit(m->md_dict, arg);
return 0;
}
PyTypeObject PyModule_Type = { PyTypeObject PyModule_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, /*ob_size*/ 0, /*ob_size*/
"module", /*tp_name*/ "module", /*tp_name*/
sizeof(PyModuleObject), /*tp_size*/ sizeof(PyModuleObject) + PyGC_HEAD_SIZE, /*tp_size*/
0, /*tp_itemsize*/ 0, /*tp_itemsize*/
(destructor)module_dealloc, /*tp_dealloc*/ (destructor)module_dealloc, /*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
...@@ -223,4 +236,16 @@ PyTypeObject PyModule_Type = { ...@@ -223,4 +236,16 @@ PyTypeObject PyModule_Type = {
(setattrfunc)module_setattr, /*tp_setattr*/ (setattrfunc)module_setattr, /*tp_setattr*/
0, /*tp_compare*/ 0, /*tp_compare*/
(reprfunc)module_repr, /*tp_repr*/ (reprfunc)module_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
0, /* tp_doc */
(traverseproc)module_traverse, /* tp_traverse */
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment