[Python-checkins] r43358 - python/trunk/Modules/itertoolsmodule.c

thomas.wouters python-checkins at python.org
Mon Mar 27 23:02:14 CEST 2006


Author: thomas.wouters
Date: Mon Mar 27 23:02:13 2006
New Revision: 43358

Modified:
   python/trunk/Modules/itertoolsmodule.c
Log:

Make itertools.tee and its internal teedataobject participate in GC. This
alone does not solve the leak in test_generators, unfortunately, but it is
part of test_generators' problem and it does solve other cycles.



Modified: python/trunk/Modules/itertoolsmodule.c
==============================================================================
--- python/trunk/Modules/itertoolsmodule.c	(original)
+++ python/trunk/Modules/itertoolsmodule.c	Mon Mar 27 23:02:13 2006
@@ -340,7 +340,7 @@
 {
 	teedataobject *tdo;
 
-	tdo = PyObject_New(teedataobject, &teedataobject_type);
+	tdo = PyObject_GC_New(teedataobject, &teedataobject_type);
 	if (tdo == NULL)
 		return NULL;
 
@@ -348,6 +348,7 @@
 	tdo->nextlink = NULL;
 	Py_INCREF(it);
 	tdo->it = it;
+	PyObject_GC_Track(tdo);
 	return (PyObject *)tdo;
 }
 
@@ -381,16 +382,34 @@
 	return value;
 }
 
-static void
-teedataobject_dealloc(teedataobject *tdo)
+static int
+teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
 {
 	int i;
+	Py_VISIT(tdo->it);
+	for (i = 0; i < tdo->numread; i++)
+		Py_VISIT(tdo->values[i]);
+	Py_VISIT(tdo->nextlink);
+	return 0;
+}
 
+static int
+teedataobject_clear(teedataobject *tdo)
+{
+	int i;
+	Py_CLEAR(tdo->it);
 	for (i=0 ; i<tdo->numread ; i++)
-		Py_DECREF(tdo->values[i]);
-	Py_XDECREF(tdo->it);
-	Py_XDECREF(tdo->nextlink);
-	PyObject_Del(tdo);
+		Py_CLEAR(tdo->values[i]);
+	Py_CLEAR(tdo->nextlink);
+	return 0;
+}
+
+static void
+teedataobject_dealloc(teedataobject *tdo)
+{
+	PyObject_GC_UnTrack(tdo);
+	teedataobject_clear(tdo);
+	PyObject_GC_Del(tdo);
 }
 
 PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects.");
@@ -417,9 +436,26 @@
 	PyObject_GenericGetAttr,		/* tp_getattro */
 	0,					/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
 	teedataobject_doc,			/* tp_doc */
-	0,					/* tp_traverse */
+	(traverseproc)teedataobject_traverse,	/* tp_traverse */
+	(inquiry)teedataobject_clear,		/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	0,					/* tp_new */
+	PyObject_GC_Del,			/* tp_free */
 };
 
 
@@ -443,12 +479,19 @@
 	return value;
 }
 
+static int
+tee_traverse(teeobject *to, visitproc visit, void *arg)
+{
+	Py_VISIT((PyObject *)to->dataobj);
+	return 0;
+}
+
 static PyObject *
 tee_copy(teeobject *to)
 {
 	teeobject *newto;
 
-	newto = PyObject_New(teeobject, &tee_type);
+	newto = PyObject_GC_New(teeobject, &tee_type);
 	if (newto == NULL)
 		return NULL;
 	Py_INCREF(to->dataobj);
@@ -474,12 +517,13 @@
 		goto done;
 	}
 
-	to = PyObject_New(teeobject, &tee_type);
+	to = PyObject_GC_New(teeobject, &tee_type);
 	if (to == NULL) 
 		goto done;
 	to->dataobj = (teedataobject *)teedataobject_new(it);
 	to->index = 0;
 	to->weakreflist = NULL;
+	PyObject_GC_Track(to);
 done:
 	Py_XDECREF(it);
 	return (PyObject *)to;
@@ -495,13 +539,21 @@
 	return tee_fromiterable(iterable);
 }
 
-static void
-tee_dealloc(teeobject *to)
+static int
+tee_clear(teeobject *to)
 {
 	if (to->weakreflist != NULL)
 		PyObject_ClearWeakRefs((PyObject *) to);
-	Py_XDECREF(to->dataobj);
-	PyObject_Del(to);
+	Py_CLEAR(to->dataobj);
+	return 0;
+}
+
+static void
+tee_dealloc(teeobject *to)
+{
+	PyObject_GC_UnTrack(to);
+	tee_clear(to);
+	PyObject_GC_Del(to);
 }
 
 PyDoc_STRVAR(teeobject_doc,
@@ -534,10 +586,10 @@
 	0,				/* tp_getattro */
 	0,				/* tp_setattro */
 	0,				/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,		/* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,	/* tp_flags */
 	teeobject_doc,			/* tp_doc */
-	0,				/* tp_traverse */
-	0,				/* tp_clear */
+	(traverseproc)tee_traverse,	/* tp_traverse */
+	(inquiry)tee_clear,		/* tp_clear */
 	0,				/* tp_richcompare */
 	offsetof(teeobject, weakreflist),	/* tp_weaklistoffset */
 	PyObject_SelfIter,		/* tp_iter */
@@ -553,7 +605,7 @@
 	0,				/* tp_init */
 	0,				/* tp_alloc */
 	tee_new,			/* tp_new */
-	PyObject_Del,			/* tp_free */
+	PyObject_GC_Del,		/* tp_free */
 };
 
 static PyObject *


More information about the Python-checkins mailing list