summaryrefslogtreecommitdiff
path: root/psycopg/green.c
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2011-06-05 16:22:54 +0100
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2011-06-05 16:22:54 +0100
commit8f876d4b5d26a4e618d0cdcb2189b5ee3abf97c6 (patch)
treeef5ff2250178d2f0a937f103174ea3ae22fd2796 /psycopg/green.c
parentdcc9e84a68a0aa446b924c308a81605d57965859 (diff)
downloadpsycopg2-8f876d4b5d26a4e618d0cdcb2189b5ee3abf97c6.tar.gz
Avoid a deadlock using concurrent green threads on the same connection
Use the async_cursor property to store an indication that something is running (even if it is not necessarily a cursor running the query).
Diffstat (limited to 'psycopg/green.c')
-rw-r--r--psycopg/green.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/psycopg/green.c b/psycopg/green.c
index c9b6e07..65578f5 100644
--- a/psycopg/green.c
+++ b/psycopg/green.c
@@ -152,6 +152,20 @@ psyco_exec_green(connectionObject *conn, const char *command)
{
PGresult *result = NULL;
+ /* Check that there is a single concurrently executing query */
+ if (conn->async_cursor) {
+ PyErr_SetString(ProgrammingError,
+ "a single async query can be executed on the same connection");
+ goto end;
+ }
+ /* we don't care about which cursor is executing the query, and
+ * it may also be that no cursor is involved at all and this is
+ * an internal query. So just store anything in the async_cursor,
+ * respecting the code expecting it to be a weakref */
+ if (!(conn->async_cursor = PyWeakref_NewRef((PyObject*)conn, NULL))) {
+ goto end;
+ }
+
/* Send the query asynchronously */
if (0 == pq_send_query(conn, command)) {
goto end;
@@ -173,6 +187,7 @@ psyco_exec_green(connectionObject *conn, const char *command)
end:
conn->async_status = ASYNC_DONE;
+ Py_CLEAR(conn->async_cursor);
return result;
}