diff options
author | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2011-06-04 01:31:36 +0100 |
---|---|---|
committer | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2011-06-04 01:31:36 +0100 |
commit | d9c0b8166f9ba17eacb09d5861409ab862447331 (patch) | |
tree | c58184cefba8eac642c0c12d5d61562ccbeedcd4 | |
parent | 3aad3d3143a8e5963b06b8905a040521d3c3bcaa (diff) | |
download | psycopg2-d9c0b8166f9ba17eacb09d5861409ab862447331.tar.gz |
Process notifies when data is received, not when the result is parsed
Notifies process access the connection, is not limited to the result, so
There is the possibility of loss of protocol sync in multithread programs.
Closes ticket #55.
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | psycopg/connection_int.c | 2 | ||||
-rw-r--r-- | psycopg/pqpath.c | 14 |
3 files changed, 14 insertions, 4 deletions
@@ -7,6 +7,8 @@ What's new in psycopg 2.4.2 transaction property. - Psycopg doesn't execute queries at connection time to find the default isolation level. + - Fixed bug with multithread code potentially causing loss of sync + with the server communication or lock of the client (ticket #55). - Don't build mx.DateTime support if the module can't be imported (ticket #53). - Fixed escape for negative numbers prefixed by minus operator diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index 0544957..18a0a14 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -174,8 +174,6 @@ conn_notifies_process(connectionObject *self) PyObject *notify = NULL; PyObject *pid = NULL, *channel = NULL, *payload = NULL; - /* TODO: we are called without the lock! */ - while ((pgn = PQnotifies(self->pgconn)) != NULL) { Dprintf("conn_notifies_process: got NOTIFY from pid %d, msg = %s", diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c index a188deb..e1a4f5f 100644 --- a/psycopg/pqpath.c +++ b/psycopg/pqpath.c @@ -665,11 +665,14 @@ pq_is_busy(connectionObject *conn) res = PQisBusy(conn->pgconn); + Py_BLOCK_THREADS; + conn_notifies_process(conn); + Py_UNBLOCK_THREADS; + pthread_mutex_unlock(&(conn->lock)); Py_END_ALLOW_THREADS; conn_notice_process(conn); - conn_notifies_process(conn); return res; } @@ -781,6 +784,14 @@ pq_execute(cursorObject *curs, const char *query, int async) } return -1; } + + /* Process notifies here instead of when fetching the tuple as we are + * into the same critical section that received the data. Without this + * care, reading notifies may disrupt other thread communications. + * (as in ticket #55). */ + Py_BLOCK_THREADS; + conn_notifies_process(curs->conn); + Py_UNBLOCK_THREADS; } else if (async == 1) { @@ -1370,7 +1381,6 @@ pq_fetch(cursorObject *curs) } conn_notice_process(curs->conn); - conn_notifies_process(curs->conn); /* error checking, close the connection if necessary (some critical errors are not really critical, like a COPY FROM error: if that's the case we |