diff options
author | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2012-11-24 22:49:36 +0000 |
---|---|---|
committer | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2012-11-24 22:49:36 +0000 |
commit | 362c2ae597122f253123213f3de57fa5cb26c7dd (patch) | |
tree | 4e09fa8ceddea87ec9423f02f3ef0fdf76ff837b | |
parent | 896ad7c827f232657cd179e01a69754e08e89f1f (diff) | |
download | psycopg2-362c2ae597122f253123213f3de57fa5cb26c7dd.tar.gz |
Release the GIL around PQgetResult calls after COPY
It should fix ticket #140.
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | psycopg/pqpath.c | 22 |
2 files changed, 18 insertions, 5 deletions
@@ -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); |