diff options
| author | Federico Di Gregorio <fog@initd.org> | 2010-04-05 16:52:25 +0200 | 
|---|---|---|
| committer | Federico Di Gregorio <fog@initd.org> | 2010-04-05 16:52:25 +0200 | 
| commit | c1a24f4ca279f8057f9f7a3fe06e9c8a5b1dc818 (patch) | |
| tree | 013197ad587c453eb5cf1dbf519e1958f099e9c6 | |
| parent | e15bc9da05721a22e986feb0363da8c5e4eb2641 (diff) | |
| download | psycopg2-c1a24f4ca279f8057f9f7a3fe06e9c8a5b1dc818.tar.gz | |
NOTIFYs fix and poll status changes
POLL_OK has been changed from 3 to 0 to let the user specify a short loop
just as "if not curs.poll()" instead of having to check for write and read
separately. For an example of this, see examples/notify.py.
| -rw-r--r-- | ChangeLog | 6 | ||||
| -rw-r--r-- | examples/notify.py | 2 | ||||
| -rw-r--r-- | lib/extensions.py | 4 | ||||
| -rw-r--r-- | psycopg/connection.h | 5 | ||||
| -rw-r--r-- | psycopg/cursor.h | 6 | ||||
| -rw-r--r-- | psycopg/cursor_int.c | 13 | ||||
| -rw-r--r-- | psycopg/cursor_type.c | 7 | 
7 files changed, 25 insertions, 18 deletions
| @@ -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*/ | 
