summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--examples/notify.py2
-rw-r--r--lib/extensions.py4
-rw-r--r--psycopg/connection.h5
-rw-r--r--psycopg/cursor.h6
-rw-r--r--psycopg/cursor_int.c13
-rw-r--r--psycopg/cursor_type.c7
7 files changed, 25 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index b355bd5..20af440 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-04-05 Federico Di Gregorio <fog@initd.org>
+
+ * Fixed problem with asynchronous NOTIFYs.
+
+ * Integrated async pacthes from Jan's git tree.
+
2010-03-13 Federico Di Gregorio <fog@initd.org>
* Release 2.0.14.
diff --git a/examples/notify.py b/examples/notify.py
index b5a613d..c88098a 100644
--- a/examples/notify.py
+++ b/examples/notify.py
@@ -39,5 +39,5 @@ while 1:
if select.select([curs],[],[],5)==([],[],[]):
print "Timeout"
else:
- if curs.isready():
+ if not curs.poll():
print "Got NOTIFY: %s" % str(curs.connection.notifies.pop())
diff --git a/lib/extensions.py b/lib/extensions.py
index 64ea7cb..edffee9 100644
--- a/lib/extensions.py
+++ b/lib/extensions.py
@@ -76,10 +76,10 @@ STATUS_ASYNC = 4
# This is a usefull mnemonic to check if the connection is in a transaction
STATUS_IN_TRANSACTION = STATUS_BEGIN
-"""psycopg async connection polling values"""
+"""psycopg asynchronous connection polling values"""
+POLL_OK = 0
POLL_READ = 1
POLL_WRITE = 2
-POLL_OK = 3
"""Backend transaction status values."""
TRANSACTION_STATUS_IDLE = 0
diff --git a/psycopg/connection.h b/psycopg/connection.h
index c0fec18..ec8e869 100644
--- a/psycopg/connection.h
+++ b/psycopg/connection.h
@@ -53,11 +53,10 @@ extern "C" {
#define ASYNC_READ 1
#define ASYNC_WRITE 2
-/* polling result, try to keep in sync with PostgresPollingStatusType from
- libpq-fe.h */
+/* polling result */
+#define PSYCO_POLL_OK 0
#define PSYCO_POLL_READ 1
#define PSYCO_POLL_WRITE 2
-#define PSYCO_POLL_OK 3
/* Hard limit on the notices stored by the Python connection */
#define CONN_NOTICES_LIMIT 50
diff --git a/psycopg/cursor.h b/psycopg/cursor.h
index bbe80ea..a0a3a82 100644
--- a/psycopg/cursor.h
+++ b/psycopg/cursor.h
@@ -62,10 +62,10 @@ typedef struct {
PyObject *pgstatus; /* last message from the server after an execute */
Oid lastoid; /* last oid from an insert or InvalidOid */
- PyObject *casts; /* an array (tuple) of typecast functions */
- PyObject *caster; /* the current typecaster object */
+ PyObject *casts; /* an array (tuple) of typecast functions */
+ PyObject *caster; /* the current typecaster object */
- PyObject *copyfile; /* file-like used during COPY TO/FROM ops */
+ PyObject *copyfile; /* file-like used during COPY TO/FROM ops */
Py_ssize_t copysize; /* size of the copy buffer during COPY TO/FROM ops */
#define DEFAULT_COPYSIZE 16384
#define DEFAULT_COPYBUFF 8132
diff --git a/psycopg/cursor_int.c b/psycopg/cursor_int.c
index 4a63f0c..1147284 100644
--- a/psycopg/cursor_int.c
+++ b/psycopg/cursor_int.c
@@ -141,9 +141,16 @@ curs_poll_fetch(cursorObject *self)
return PyInt_FromLong(PSYCO_POLL_READ);
}
- /* data has arrived, try to fetch all of it or, if it failed, tell the
- user to wait more */
- last_result = curs_get_last_result(self);
+ /* try to fetch the data only if this was a poll following a read
+ request; else just return POLL_OK to the user: this is necessary
+ because of asynchronous NOTIFYs that can be sent by the backend
+ even if the user didn't asked for them */
+
+ if (self->conn->async_status == ASYNC_READ)
+ last_result = curs_get_last_result(self);
+ else
+ last_result = 0;
+
if (last_result == 0) {
Dprintf("cur_poll_fetch: returning %d", PSYCO_POLL_OK);
return PyInt_FromLong(PSYCO_POLL_OK);
diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c
index 73217c2..895b3ce 100644
--- a/psycopg/cursor_type.c
+++ b/psycopg/cursor_type.c
@@ -1485,14 +1485,9 @@ psyco_curs_poll(cursorObject *self)
if (self->conn->async_status == ASYNC_WRITE) {
return curs_poll_send(self);
}
- else if (self->conn->async_status == ASYNC_READ) {
+ else {
return curs_poll_fetch(self);
}
- else {
- PyErr_Format(OperationalError, "unexpected execution status: %d",
- self->conn->async_status);
- return NULL;
- }
}
/* extension: closed - return true if cursor is closed*/