summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Henstridge <james@jamesh.id.au>2008-05-28 09:00:36 +0800
committerJames Henstridge <james@jamesh.id.au>2008-05-28 09:00:36 +0800
commita39fb19eb9db28205510aff445214b6c8004b7d8 (patch)
treecebd034b71336e8dfbd2fa14f5e419cb31b8c4f8
parent607319331410a21111965727ebea9ac1d9dd8f23 (diff)
downloadpsycopg2-a39fb19eb9db28205510aff445214b6c8004b7d8.tar.gz
* psycopg/connection_type.c:
* psycopg/cursor_type.c: add support for cyclic GC. * psycopg/python.h: add definitions for Py_CLEAR() and Py_VISIT() for compatibility with old versions of Python.
-rw-r--r--psycopg/connection_type.c28
-rw-r--r--psycopg/cursor_type.c42
-rw-r--r--psycopg/python.h23
3 files changed, 73 insertions, 20 deletions
diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c
index 3cdbf1f..a7be658 100644
--- a/psycopg/connection_type.c
+++ b/psycopg/connection_type.c
@@ -450,11 +450,11 @@ connection_dealloc(PyObject* obj)
if (self->encoding) free(self->encoding);
if (self->critical) free(self->critical);
- Py_XDECREF(self->notice_list);
- Py_XDECREF(self->notifies);
- Py_XDECREF(self->async_cursor);
- Py_XDECREF(self->string_types);
- Py_XDECREF(self->binary_types);
+ Py_CLEAR(self->notice_list);
+ Py_CLEAR(self->notifies);
+ Py_CLEAR(self->async_cursor);
+ Py_CLEAR(self->string_types);
+ Py_CLEAR(self->binary_types);
pthread_mutex_destroy(&(self->lock));
@@ -486,7 +486,7 @@ connection_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static void
connection_del(PyObject* self)
{
- PyObject_Del(self);
+ PyObject_GC_Del(self);
}
static PyObject *
@@ -497,6 +497,18 @@ connection_repr(connectionObject *self)
self, self->dsn, self->closed);
}
+static int
+connection_traverse(connectionObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->async_cursor);
+ Py_VISIT(self->notice_list);
+ Py_VISIT(self->notice_filter);
+ Py_VISIT(self->notifies);
+ Py_VISIT(self->string_types);
+ Py_VISIT(self->binary_types);
+ return 0;
+}
+
/* object type */
@@ -530,10 +542,10 @@ PyTypeObject connectionType = {
0, /*tp_setattro*/
0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
connectionType_doc, /*tp_doc*/
- 0, /*tp_traverse*/
+ (traverseproc)connection_traverse, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c
index 5b0cd02..03be9d9 100644
--- a/psycopg/cursor_type.c
+++ b/psycopg/cursor_type.c
@@ -1634,15 +1634,15 @@ cursor_dealloc(PyObject* obj)
if (self->name) PyMem_Free(self->name);
- Py_XDECREF((PyObject*)self->conn);
- Py_XDECREF(self->casts);
- Py_XDECREF(self->description);
- Py_XDECREF(self->pgstatus);
- Py_XDECREF(self->tuple_factory);
- Py_XDECREF(self->tzinfo_factory);
- Py_XDECREF(self->query);
- Py_XDECREF(self->string_types);
- Py_XDECREF(self->binary_types);
+ Py_CLEAR(self->conn);
+ Py_CLEAR(self->casts);
+ Py_CLEAR(self->description);
+ Py_CLEAR(self->pgstatus);
+ Py_CLEAR(self->tuple_factory);
+ Py_CLEAR(self->tzinfo_factory);
+ Py_CLEAR(self->query);
+ Py_CLEAR(self->string_types);
+ Py_CLEAR(self->binary_types);
IFCLEARPGRES(self->pgres);
@@ -1675,7 +1675,7 @@ cursor_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static void
cursor_del(PyObject* self)
{
- PyObject_Del(self);
+ PyObject_GC_Del(self);
}
static PyObject *
@@ -1685,6 +1685,23 @@ cursor_repr(cursorObject *self)
"<cursor object at %p; closed: %d>", self, self->closed);
}
+static int
+cursor_traverse(cursorObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->conn);
+ Py_VISIT(self->description);
+ Py_VISIT(self->pgstatus);
+ Py_VISIT(self->casts);
+ Py_VISIT(self->caster);
+ Py_VISIT(self->copyfile);
+ Py_VISIT(self->tuple_factory);
+ Py_VISIT(self->tzinfo_factory);
+ Py_VISIT(self->query);
+ Py_VISIT(self->string_types);
+ Py_VISIT(self->binary_types);
+ return 0;
+}
+
/* object type */
@@ -1714,10 +1731,11 @@ PyTypeObject cursorType = {
0, /*tp_setattro*/
0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_ITER |
+ Py_TPFLAGS_HAVE_GC, /*tp_flags*/
cursorType_doc, /*tp_doc*/
- 0, /*tp_traverse*/
+ (traverseproc)cursor_traverse, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
diff --git a/psycopg/python.h b/psycopg/python.h
index 84bacaa..13d6ce7 100644
--- a/psycopg/python.h
+++ b/psycopg/python.h
@@ -41,4 +41,27 @@
#define freefunc destructor
#endif
+/* Py_VISIT and Py_CLEAR introduced in Python 2.4 */
+#ifndef Py_VISIT
+#define Py_VISIT(op) \
+ do { \
+ if (op) { \
+ int vret = visit((op), arg); \
+ if (vret) \
+ return vret; \
+ } \
+ } while (0)
+#endif
+
+#ifndef Py_CLEAR
+#define Py_CLEAR(op) \
+ do { \
+ if (op) { \
+ PyObject *tmp = (PyObject *)(op); \
+ (op) = NULL; \
+ Py_DECREF(tmp); \
+ } \
+ } while (0)
+#endif
+
#endif /* !defined(PSYCOPG_PYTHON_H) */