summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2012-11-24 22:49:36 +0000
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2012-11-24 22:49:36 +0000
commit362c2ae597122f253123213f3de57fa5cb26c7dd (patch)
tree4e09fa8ceddea87ec9423f02f3ef0fdf76ff837b
parent896ad7c827f232657cd179e01a69754e08e89f1f (diff)
downloadpsycopg2-362c2ae597122f253123213f3de57fa5cb26c7dd.tar.gz
Release the GIL around PQgetResult calls after COPY
It should fix ticket #140.
-rw-r--r--NEWS1
-rw-r--r--psycopg/pqpath.c22
2 files changed, 18 insertions, 5 deletions
diff --git a/NEWS b/NEWS
index 0efd962..a30addf 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,7 @@ What's new in psycopg 2.4.6
when a connection string is specified as well (ticket #131).
- Discard any result produced by 'executemany()' (ticket #133).
- Fixed pickling of FixedOffsetTimezone objects (ticket #135).
+ - Release the GIL around PQgetResult calls after COPY (ticket #140).
- 'errorcodes' map updated to PostgreSQL 9.2.
diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c
index 4e9d69f..641a5af 100644
--- a/psycopg/pqpath.c
+++ b/psycopg/pqpath.c
@@ -986,7 +986,7 @@ pq_send_query(connectionObject *conn, const char *query)
/* Return the last result available on the connection.
*
- * The function will block will block only if a command is active and the
+ * The function will block only if a command is active and the
* necessary response data has not yet been read by PQconsumeInput.
*
* The result should be disposed using PQclear()
@@ -1312,9 +1312,9 @@ _pq_copy_in_v3(cursorObject *curs)
res = PQputCopyEnd(curs->conn->pgconn, "error in .read() call");
IFCLEARPGRES(curs->pgres);
-
+
Dprintf("_pq_copy_in_v3: copy ended; res = %d", res);
-
+
/* if the result is -1 we should not even try to get a result from the
bacause that will lock the current thread forever */
if (res == -1) {
@@ -1326,7 +1326,13 @@ _pq_copy_in_v3(cursorObject *curs)
}
else {
/* and finally we grab the operation result from the backend */
- while ((curs->pgres = PQgetResult(curs->conn->pgconn)) != NULL) {
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS;
+ curs->pgres = PQgetResult(curs->conn->pgconn);
+ Py_END_ALLOW_THREADS;
+
+ if (NULL == curs->pgres)
+ break;
if (PQresultStatus(curs->pgres) == PGRES_FATAL_ERROR)
pq_raise(curs->conn, curs, NULL);
IFCLEARPGRES(curs->pgres);
@@ -1396,7 +1402,13 @@ _pq_copy_out_v3(cursorObject *curs)
/* and finally we grab the operation result from the backend */
IFCLEARPGRES(curs->pgres);
- while ((curs->pgres = PQgetResult(curs->conn->pgconn)) != NULL) {
+ for (;;) {
+ Py_BEGIN_ALLOW_THREADS;
+ curs->pgres = PQgetResult(curs->conn->pgconn);
+ Py_END_ALLOW_THREADS;
+
+ if (NULL == curs->pgres)
+ break;
if (PQresultStatus(curs->pgres) == PGRES_FATAL_ERROR)
pq_raise(curs->conn, curs, NULL);
IFCLEARPGRES(curs->pgres);