summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2011-06-04 01:49:03 +0100
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2011-06-04 01:49:03 +0100
commit05659c0d16767f0cba55d0e6acfbe3748aacc719 (patch)
tree3a8905361ed322fca700219742fb075e61f09eae
parentd9c0b8166f9ba17eacb09d5861409ab862447331 (diff)
downloadpsycopg2-05659c0d16767f0cba55d0e6acfbe3748aacc719.tar.gz
Cleanup of notice processing
The function is always called in the context of functions grabbing the connection lock, so just use the same critical section instead of releasing and re-acquiring it. It is not a problem as serious as the notifies process (ticket #55) as the notices are a psycopg structure, not libpq. However the change allows again processing notices/notifies in the same place, which makes sense conceptually, plus we save some lock dance.
-rw-r--r--psycopg/connection_int.c19
-rw-r--r--psycopg/pqpath.c30
2 files changed, 22 insertions, 27 deletions
diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c
index 18a0a14..24d424d 100644
--- a/psycopg/connection_int.c
+++ b/psycopg/connection_int.c
@@ -95,6 +95,10 @@ conn_notice_callback(void *args, const char *message)
self->notice_pending = notice;
}
+/* Expose the notices received as Python objects.
+ *
+ * The function should be called with the connection lock and the GIL.
+ */
void
conn_notice_process(connectionObject *self)
{
@@ -105,10 +109,6 @@ conn_notice_process(connectionObject *self)
return;
}
- Py_BEGIN_ALLOW_THREADS;
- pthread_mutex_lock(&self->lock);
- Py_BLOCK_THREADS;
-
notice = self->notice_pending;
nnotices = PyList_GET_SIZE(self->notice_list);
@@ -132,10 +132,6 @@ conn_notice_process(connectionObject *self)
0, nnotices - CONN_NOTICES_LIMIT);
}
- Py_UNBLOCK_THREADS;
- pthread_mutex_unlock(&self->lock);
- Py_END_ALLOW_THREADS;
-
conn_notice_clean(self);
}
@@ -143,8 +139,6 @@ void
conn_notice_clean(connectionObject *self)
{
struct connectionObject_notice *tmp, *notice;
- Py_BEGIN_ALLOW_THREADS;
- pthread_mutex_lock(&self->lock);
notice = self->notice_pending;
@@ -154,11 +148,8 @@ conn_notice_clean(connectionObject *self)
free((void*)tmp->message);
free(tmp);
}
-
+
self->notice_pending = NULL;
-
- pthread_mutex_unlock(&self->lock);
- Py_END_ALLOW_THREADS;
}
diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c
index e1a4f5f..f50b00b 100644
--- a/psycopg/pqpath.c
+++ b/psycopg/pqpath.c
@@ -450,11 +450,13 @@ pq_commit(connectionObject *conn)
retvalue = pq_execute_command_locked(conn, "COMMIT", &pgres, &error, &_save);
+ Py_BLOCK_THREADS;
+ conn_notice_process(conn);
+ Py_UNBLOCK_THREADS;
+
pthread_mutex_unlock(&conn->lock);
Py_END_ALLOW_THREADS;
- conn_notice_process(conn);
-
if (retvalue < 0)
pq_complete_error(conn, &pgres, &error);
@@ -512,11 +514,13 @@ pq_abort(connectionObject *conn)
retvalue = pq_abort_locked(conn, &pgres, &error, &_save);
+ Py_BLOCK_THREADS;
+ conn_notice_process(conn);
+ Py_UNBLOCK_THREADS;
+
pthread_mutex_unlock(&conn->lock);
Py_END_ALLOW_THREADS;
- conn_notice_process(conn);
-
if (retvalue < 0)
pq_complete_error(conn, &pgres, &error);
@@ -576,11 +580,13 @@ pq_reset(connectionObject *conn)
retvalue = pq_reset_locked(conn, &pgres, &error, &_save);
+ Py_BLOCK_THREADS;
+ conn_notice_process(conn);
+ Py_UNBLOCK_THREADS;
+
pthread_mutex_unlock(&conn->lock);
Py_END_ALLOW_THREADS;
- conn_notice_process(conn);
-
if (retvalue < 0) {
pq_complete_error(conn, &pgres, &error);
}
@@ -667,13 +673,12 @@ pq_is_busy(connectionObject *conn)
Py_BLOCK_THREADS;
conn_notifies_process(conn);
+ conn_notice_process(conn);
Py_UNBLOCK_THREADS;
pthread_mutex_unlock(&(conn->lock));
Py_END_ALLOW_THREADS;
- conn_notice_process(conn);
-
return res;
}
@@ -693,9 +698,9 @@ pq_is_busy_locked(connectionObject *conn)
return -1;
}
- /* We can't call conn_notice_process/conn_notifies_process because
- they try to get the lock. We don't need anyway them because at the end of
- the loop we are in (async reading) pq_fetch will be called. */
+ /* notices and notifies will be processed at the end of the loop we are in
+ * (async reading) by pq_fetch. */
+
return PQisBusy(conn->pgconn);
}
@@ -791,6 +796,7 @@ pq_execute(cursorObject *curs, const char *query, int async)
* (as in ticket #55). */
Py_BLOCK_THREADS;
conn_notifies_process(curs->conn);
+ conn_notice_process(curs->conn);
Py_UNBLOCK_THREADS;
}
@@ -1380,8 +1386,6 @@ pq_fetch(cursorObject *curs)
break;
}
- conn_notice_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
raise the exception but we avoid to close the connection) */