Some improvements to connection/cursor GC

Provide a tp_clear, make sure that GC_UnTrack is called before clearing.
This commit is contained in:
Daniele Varrazzo 2013-03-21 12:55:17 +00:00
parent 3b8abf3fc4
commit 5aafe38fd7
2 changed files with 42 additions and 26 deletions

View File

@ -1116,18 +1116,31 @@ exit:
return res; 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 static void
connection_dealloc(PyObject* obj) connection_dealloc(PyObject* obj)
{ {
connectionObject *self = (connectionObject *)obj; connectionObject *self = (connectionObject *)obj;
if (self->weakreflist) { conn_close(self);
PyObject_ClearWeakRefs(obj);
}
PyObject_GC_UnTrack(self); PyObject_GC_UnTrack(self);
conn_close(self); if (self->weakreflist) {
PyObject_ClearWeakRefs(obj);
}
conn_notice_clean(self); conn_notice_clean(self);
@ -1137,13 +1150,7 @@ connection_dealloc(PyObject* obj)
if (self->critical) free(self->critical); if (self->critical) free(self->critical);
if (self->cancel) PQfreeCancel(self->cancel); if (self->cancel) PQfreeCancel(self->cancel);
Py_CLEAR(self->tpc_xid); connection_clear(self);
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);
pthread_mutex_destroy(&(self->lock)); pthread_mutex_destroy(&(self->lock));
@ -1229,7 +1236,7 @@ PyTypeObject connectionType = {
/*tp_flags*/ /*tp_flags*/
connectionType_doc, /*tp_doc*/ connectionType_doc, /*tp_doc*/
(traverseproc)connection_traverse, /*tp_traverse*/ (traverseproc)connection_traverse, /*tp_traverse*/
0, /*tp_clear*/ (inquiry)connection_clear, /*tp_clear*/
0, /*tp_richcompare*/ 0, /*tp_richcompare*/
offsetof(connectionObject, weakreflist), /* tp_weaklistoffset */ offsetof(connectionObject, weakreflist), /* tp_weaklistoffset */
0, /*tp_iter*/ 0, /*tp_iter*/

View File

@ -1864,28 +1864,37 @@ cursor_setup(cursorObject *self, connectionObject *conn, const char *name)
return 0; return 0;
} }
static void static int
cursor_dealloc(PyObject* obj) 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->conn);
Py_CLEAR(self->casts);
Py_CLEAR(self->description); Py_CLEAR(self->description);
Py_CLEAR(self->pgstatus); Py_CLEAR(self->pgstatus);
Py_CLEAR(self->casts);
Py_CLEAR(self->caster);
Py_CLEAR(self->copyfile);
Py_CLEAR(self->tuple_factory); Py_CLEAR(self->tuple_factory);
Py_CLEAR(self->tzinfo_factory); Py_CLEAR(self->tzinfo_factory);
Py_CLEAR(self->query); Py_CLEAR(self->query);
Py_CLEAR(self->string_types); Py_CLEAR(self->string_types);
Py_CLEAR(self->binary_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); CLEARPGRES(self->pgres);
@ -1988,7 +1997,7 @@ PyTypeObject cursorType = {
/*tp_flags*/ /*tp_flags*/
cursorType_doc, /*tp_doc*/ cursorType_doc, /*tp_doc*/
(traverseproc)cursor_traverse, /*tp_traverse*/ (traverseproc)cursor_traverse, /*tp_traverse*/
0, /*tp_clear*/ (inquiry)cursor_clear, /*tp_clear*/
0, /*tp_richcompare*/ 0, /*tp_richcompare*/
offsetof(cursorObject, weakreflist), /*tp_weaklistoffset*/ offsetof(cursorObject, weakreflist), /*tp_weaklistoffset*/
cursor_iter, /*tp_iter*/ cursor_iter, /*tp_iter*/