From 5aafe38fd74ea8468fbae3fccae69fc7aa3bd060 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Thu, 21 Mar 2013 12:55:17 +0000 Subject: [PATCH] Some improvements to connection/cursor GC Provide a tp_clear, make sure that GC_UnTrack is called before clearing. --- psycopg/connection_type.c | 31 +++++++++++++++++++------------ psycopg/cursor_type.c | 37 +++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index 1192a4ac..79d11aa1 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -1116,18 +1116,31 @@ exit: return res; } +static int +connection_clear(connectionObject *self) +{ + Py_CLEAR(self->tpc_xid); + Py_CLEAR(self->async_cursor); + Py_CLEAR(self->notice_list); + Py_CLEAR(self->notice_filter); + Py_CLEAR(self->notifies); + Py_CLEAR(self->string_types); + Py_CLEAR(self->binary_types); + return 0; +} + static void connection_dealloc(PyObject* obj) { connectionObject *self = (connectionObject *)obj; - if (self->weakreflist) { - PyObject_ClearWeakRefs(obj); - } + conn_close(self); PyObject_GC_UnTrack(self); - conn_close(self); + if (self->weakreflist) { + PyObject_ClearWeakRefs(obj); + } conn_notice_clean(self); @@ -1137,13 +1150,7 @@ connection_dealloc(PyObject* obj) if (self->critical) free(self->critical); if (self->cancel) PQfreeCancel(self->cancel); - Py_CLEAR(self->tpc_xid); - Py_CLEAR(self->async_cursor); - Py_CLEAR(self->notice_list); - Py_CLEAR(self->notice_filter); - Py_CLEAR(self->notifies); - Py_CLEAR(self->string_types); - Py_CLEAR(self->binary_types); + connection_clear(self); pthread_mutex_destroy(&(self->lock)); @@ -1229,7 +1236,7 @@ PyTypeObject connectionType = { /*tp_flags*/ connectionType_doc, /*tp_doc*/ (traverseproc)connection_traverse, /*tp_traverse*/ - 0, /*tp_clear*/ + (inquiry)connection_clear, /*tp_clear*/ 0, /*tp_richcompare*/ offsetof(connectionObject, weakreflist), /* tp_weaklistoffset */ 0, /*tp_iter*/ diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c index 8794e7fe..983c4a9c 100644 --- a/psycopg/cursor_type.c +++ b/psycopg/cursor_type.c @@ -1864,28 +1864,37 @@ cursor_setup(cursorObject *self, connectionObject *conn, const char *name) return 0; } -static void -cursor_dealloc(PyObject* obj) +static int +cursor_clear(cursorObject *self) { - cursorObject *self = (cursorObject *)obj; - - if (self->weakreflist) { - PyObject_ClearWeakRefs(obj); - } - - PyObject_GC_UnTrack(self); - - PyMem_Free(self->name); - Py_CLEAR(self->conn); - Py_CLEAR(self->casts); Py_CLEAR(self->description); Py_CLEAR(self->pgstatus); + Py_CLEAR(self->casts); + Py_CLEAR(self->caster); + Py_CLEAR(self->copyfile); Py_CLEAR(self->tuple_factory); Py_CLEAR(self->tzinfo_factory); Py_CLEAR(self->query); Py_CLEAR(self->string_types); Py_CLEAR(self->binary_types); + return 0; +} + +static void +cursor_dealloc(PyObject* obj) +{ + cursorObject *self = (cursorObject *)obj; + + PyObject_GC_UnTrack(self); + + if (self->weakreflist) { + PyObject_ClearWeakRefs(obj); + } + + cursor_clear(self); + + PyMem_Free(self->name); CLEARPGRES(self->pgres); @@ -1988,7 +1997,7 @@ PyTypeObject cursorType = { /*tp_flags*/ cursorType_doc, /*tp_doc*/ (traverseproc)cursor_traverse, /*tp_traverse*/ - 0, /*tp_clear*/ + (inquiry)cursor_clear, /*tp_clear*/ 0, /*tp_richcompare*/ offsetof(cursorObject, weakreflist), /*tp_weaklistoffset*/ cursor_iter, /*tp_iter*/