Set the execution status to ASYNC_READ after flushing all output.

Without this a query that did not get flushed completely to the server
would cause cursor.poll() to always go into the curs_poll_send()
branch even if it was retuning ASYNC_READ.

Bug report by Daniele Varrazzo.
This commit is contained in:
Jan Urbański 2010-04-11 03:48:33 +02:00 committed by Federico Di Gregorio
parent 4574bde3a2
commit 463724690c
4 changed files with 12 additions and 1 deletions

View File

@ -51,6 +51,7 @@ extern "C" {
#define CONN_STATUS_GET_CLIENT_ENCODING 10
/* async query execution status */
#define ASYNC_DONE 0
#define ASYNC_READ 1
#define ASYNC_WRITE 2

View File

@ -695,6 +695,7 @@ connection_setup(connectionObject *self, const char *dsn, long int async)
self->status = async ? CONN_STATUS_SETUP : CONN_STATUS_READY;
self->critical = NULL;
self->async_cursor = NULL;
self->async_status = ASYNC_DONE;
self->pgconn = NULL;
self->mark = 0;
self->string_types = PyDict_New();

View File

@ -112,6 +112,7 @@ curs_poll_send(cursorObject *self)
else if (res == 0) {
/* all data flushed, start waiting for results */
Dprintf("cur_poll_send: returning %d", PSYCO_POLL_READ);
self->conn->async_status = ASYNC_READ;
return PyInt_FromLong(PSYCO_POLL_READ);
}
else {
@ -153,6 +154,11 @@ curs_poll_fetch(cursorObject *self)
if (last_result == 0) {
Dprintf("cur_poll_fetch: returning %d", PSYCO_POLL_OK);
/* self->conn->async_status cannot be ASYNC_WRITE here, because we
never execute curs_poll_fetch in ASYNC_WRITE state, so we can
safely set it to ASYNC_DONE because we either fetched the result or
there is no result to fetch */
self->conn->async_status = ASYNC_DONE;
return PyInt_FromLong(PSYCO_POLL_OK);
}
else if (last_result == 1) {

View File

@ -1492,6 +1492,9 @@ psyco_curs_poll(cursorObject *self)
return curs_poll_send(self);
}
else {
/* this gets called both for ASYNC_READ and ASYNC_DONE, because even
if the async query is complete, we still might want to check for
NOTIFYs */
return curs_poll_fetch(self);
}
}