mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-11 03:26:37 +03:00
* 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.
This commit is contained in:
parent
6073193314
commit
a39fb19eb9
|
@ -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*/
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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) */
|
||||
|
|
Loading…
Reference in New Issue
Block a user