From 8cf30509ad883b7bb91b5f2bc30b1fdb0942d3b6 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Tue, 26 Aug 2014 02:27:51 +0100 Subject: [PATCH] Fixed memory leak with large objects Deallocating closed large objects failed to decrement the connection refcount. The fact the lobject is closed doesn't matter for refcount. Issue detected by the always useful scripts/refcounter.py With an extra bit of unrequested whitespace love. --- NEWS | 1 + psycopg/lobject_type.c | 13 ++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 4240045e..4fa1a0b3 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,7 @@ What's new in psycopg 2.5.4 PostgreSQL but not documented. - Make sure the internal `_psycopg.so` module can be imported stand-alone (to allow modules juggling such as the one described in :ticket:`#201`). +- Fixed memory leak with large objects (regression introduced in 2.5.3). What's new in psycopg 2.5.3 diff --git a/psycopg/lobject_type.c b/psycopg/lobject_type.c index 068923c9..47f5063a 100644 --- a/psycopg/lobject_type.c +++ b/psycopg/lobject_type.c @@ -52,7 +52,7 @@ psyco_lobj_close(lobjectObject *self, PyObject *args) opened large objects */ if (!lobject_is_closed(self) && !self->conn->autocommit - && self->conn->mark == self->mark) + && self->conn->mark == self->mark) { Dprintf("psyco_lobj_close: closing lobject at %p", self); if (lobject_close(self) < 0) @@ -171,14 +171,14 @@ psyco_lobj_seek(lobjectObject *self, PyObject *args) int pos=0; if (!PyArg_ParseTuple(args, "i|i", &offset, &whence)) - return NULL; + return NULL; EXC_IF_LOBJ_CLOSED(self); EXC_IF_LOBJ_LEVEL0(self); EXC_IF_LOBJ_UNMARKED(self); if ((pos = lobject_seek(self, offset, whence)) < 0) - return NULL; + return NULL; return PyInt_FromLong((long)pos); } @@ -198,7 +198,7 @@ psyco_lobj_tell(lobjectObject *self, PyObject *args) EXC_IF_LOBJ_UNMARKED(self); if ((pos = lobject_tell(self)) < 0) - return NULL; + return NULL; return PyInt_FromLong((long)pos); } @@ -333,11 +333,10 @@ lobject_setup(lobjectObject *self, connectionObject *conn, return -1; } + Py_INCREF((PyObject*)conn); self->conn = conn; self->mark = conn->mark; - Py_INCREF((PyObject*)self->conn); - self->fd = -1; self->oid = InvalidOid; @@ -358,8 +357,8 @@ lobject_dealloc(PyObject* obj) if (self->conn && self->fd != -1) { if (lobject_close(self) < 0) PyErr_Print(); - Py_XDECREF((PyObject*)self->conn); } + Py_CLEAR(self->conn); PyMem_Free(self->smode); Dprintf("lobject_dealloc: deleted lobject object at %p, refcnt = "