Added patch for refcount bug in copy_from

By Dave Malcolm. https://bugzilla.redhat.com/show_bug.cgi?id=711095
(slightly edited to increment the refcount before storing the pointer
in the cursor).
This commit is contained in:
Daniele Varrazzo 2011-06-06 23:47:13 +01:00
parent 2a1b2b5713
commit 1888bf41c0
2 changed files with 10 additions and 2 deletions

2
NEWS
View File

@ -13,6 +13,8 @@ What's new in psycopg 2.4.2
support was built (ticket #53). support was built (ticket #53).
- Fixed escape for negative numbers prefixed by minus operator - Fixed escape for negative numbers prefixed by minus operator
(ticket #57). (ticket #57).
- Fixed refcount issue during copy. Reported and fixed by Dave
Malcolm (ticket #58, Red Hat Bug 711095).
- Trying to execute concurrent operations on the same connection - Trying to execute concurrent operations on the same connection
through concurrent green thread results in an error instead of a through concurrent green thread results in an error instead of a
deadlock. deadlock.

View File

@ -1220,8 +1220,12 @@ _psyco_curs_has_read_check(PyObject* o, void* var)
{ {
if (PyObject_HasAttrString(o, "readline") if (PyObject_HasAttrString(o, "readline")
&& PyObject_HasAttrString(o, "read")) { && PyObject_HasAttrString(o, "read")) {
/* It's OK to store a borrowed reference, because it is only held for /* This routine stores a borrowed reference. Although it is only held
* the duration of psyco_curs_copy_from. */ * for the duration of psyco_curs_copy_from, nested invocations of
* Py_BEGIN_ALLOW_THREADS could surrender control to another thread,
* which could invoke the garbage collector. We thus need an
* INCREF/DECREF pair if we store this pointer in a GC object, such as
* a cursorObject */
*((PyObject**)var) = o; *((PyObject**)var) = o;
return 1; return 1;
} }
@ -1311,6 +1315,7 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
Dprintf("psyco_curs_copy_from: query = %s", query); Dprintf("psyco_curs_copy_from: query = %s", query);
self->copysize = bufsize; self->copysize = bufsize;
Py_INCREF(file);
self->copyfile = file; self->copyfile = file;
if (pq_execute(self, query, 0) == 1) { if (pq_execute(self, query, 0) == 1) {
@ -1319,6 +1324,7 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
} }
self->copyfile = NULL; self->copyfile = NULL;
Py_DECREF(file);
exit: exit:
PyMem_Free(quoted_delimiter); PyMem_Free(quoted_delimiter);