[Python-checkins] r69644 - in python/branches/io-c/Modules: _bytesio.c _iobase.c

antoine.pitrou python-checkins at python.org
Sun Feb 15 18:59:30 CET 2009


Author: antoine.pitrou
Date: Sun Feb 15 18:59:30 2009
New Revision: 69644

Log:
Fix memory leak in destructor when a Python class inherits from IOBase (or an IOBase-derived type)



Modified:
   python/branches/io-c/Modules/_bytesio.c
   python/branches/io-c/Modules/_iobase.c

Modified: python/branches/io-c/Modules/_bytesio.c
==============================================================================
--- python/branches/io-c/Modules/_bytesio.c	(original)
+++ python/branches/io-c/Modules/_bytesio.c	Sun Feb 15 18:59:30 2009
@@ -536,22 +536,22 @@
 static PyObject *
 bytesio_write(BytesIOObject *self, PyObject *obj)
 {
-    const char *bytes;
-    Py_ssize_t size;
     Py_ssize_t n = 0;
+    Py_buffer buf;
+    PyObject *result = NULL;
 
     CHECK_CLOSED(self);
 
-    if (PyObject_AsReadBuffer(obj, (void *)&bytes, &size) < 0)
+    if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0)
         return NULL;
 
-    if (size != 0) {
-        n = write_bytes(self, bytes, size);
-        if (n < 0)
-            return NULL;
-    }
+    if (buf.len != 0)
+        n = write_bytes(self, buf.buf, buf.len);
+    if (n >= 0)
+        result = PyLong_FromSsize_t(n);
 
-    return PyLong_FromSsize_t(n);
+    PyBuffer_Release(&buf);
+    return result;
 }
 
 PyDoc_STRVAR(writelines_doc,
@@ -611,6 +611,9 @@
         PyMem_Free(self->buf);
         self->buf = NULL;
     }
+    Py_CLEAR(self->dict);
+    if (self->weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *)self);
     Py_TYPE(self)->tp_free(self);
 }
 

Modified: python/branches/io-c/Modules/_iobase.c
==============================================================================
--- python/branches/io-c/Modules/_iobase.c	(original)
+++ python/branches/io-c/Modules/_iobase.c	Sun Feb 15 18:59:30 2009
@@ -193,6 +193,7 @@
 {
     PyObject *res;
     PyObject *tp, *v, *tb;
+    PyObject **dictptr;
     int closed = 1;
     PyErr_Fetch(&tp, &v, &tb);
     /* We need to resurrect the object as calling close() can invoke
@@ -217,9 +218,14 @@
         else
             Py_DECREF(res);
     }
+    /* The code above might have re-added a dict, DECREF it */
+    dictptr = _PyObject_GetDictPtr(self);
+    if (dictptr != NULL)
+        Py_CLEAR(*dictptr);
     PyErr_Restore(tp, v, tb);
-    if (--((PyObject *) self)->ob_refcnt != 0)
+    if (--((PyObject *) self)->ob_refcnt != 0) {
         return -1;
+    }
     return 0;
 }
 
@@ -670,14 +676,6 @@
     0,                          /* tp_init */
     0,                          /* tp_alloc */
     PyType_GenericNew,          /* tp_new */
-    0,                          /* tp_free */
-    0,                          /* tp_is_gc */
-    0,                          /* tp_bases */
-    0,                          /* tp_mro */
-    0,                          /* tp_cache */
-    0,                          /* tp_subclasses */
-    0,                          /* tp_weaklist */
-    0,                          /* tp_del */
 };
 
 


More information about the Python-checkins mailing list