summaryrefslogtreecommitdiff
path: root/psycopg/connection_int.c
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2010-04-22 14:46:19 +0100
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2010-04-23 13:24:35 +0100
commit5be0fc52ca79832c029b4a67a3c470244bdda3a0 (patch)
tree73604435c476494a279db45662c3ef12e5b80291 /psycopg/connection_int.c
parentdf959c20bee9e4f0e452731c9d79e0578f3f01b0 (diff)
downloadpsycopg2-5be0fc52ca79832c029b4a67a3c470244bdda3a0.tar.gz
Reusable parts of the green polling refactored out.
The functions _conn_poll_connecting() and _conn_poll_query() will be usable by the async connections too.
Diffstat (limited to 'psycopg/connection_int.c')
-rw-r--r--psycopg/connection_int.c179
1 files changed, 104 insertions, 75 deletions
diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c
index 891d0bf..0d9da09 100644
--- a/psycopg/connection_int.c
+++ b/psycopg/connection_int.c
@@ -749,104 +749,133 @@ conn_poll_fetch(connectionObject *self)
}
}
-/* conn_poll_green - poll a *sync* connection with external wait */
+/* poll during a connection attempt until the connection has established. */
-PyObject *
-conn_poll_green(connectionObject *self)
+int
+_conn_poll_connecting(connectionObject *self)
{
int res = PSYCO_POLL_ERROR;
- switch (self->status) {
- case CONN_STATUS_SETUP:
- Dprintf("conn_poll: status = CONN_STATUS_SETUP");
- self->status = CONN_STATUS_ASYNC;
- res = PSYCO_POLL_WRITE;
+ switch (PQconnectPoll(self->pgconn)) {
+ case PGRES_POLLING_OK:
+ res = PSYCO_POLL_OK;
+ break;
+ case PGRES_POLLING_READING:
+ res = PSYCO_POLL_READ;
break;
+ case PGRES_POLLING_WRITING:
+ res = PSYCO_POLL_WRITE;
+ break;
+ case PGRES_POLLING_FAILED:
+ case PGRES_POLLING_ACTIVE:
+ PyErr_SetString(OperationalError, "asynchronous connection failed");
+ res = PSYCO_POLL_ERROR;
+ break;
+ }
- case CONN_STATUS_ASYNC:
- Dprintf("conn_poll: status = CONN_STATUS_ASYNC");
- switch (PQconnectPoll(self->pgconn)) {
- case PGRES_POLLING_OK:
- res = PSYCO_POLL_OK;
- break;
- case PGRES_POLLING_READING:
+ return res;
+}
+
+
+/* Poll the connection for the send query/retrieve result phase
+
+ Advance the async_status (usually going WRITE -> READ -> DONE) but don't
+ mess with the connection status. */
+int
+_conn_poll_query(connectionObject *self)
+{
+ int res = PSYCO_POLL_ERROR;
+
+ switch (self->async_status) {
+ case ASYNC_WRITE:
+ Dprintf("conn_poll: async_status = ASYNC_WRITE");
+ switch (PQflush(self->pgconn)) {
+ case 0: /* success */
+ /* we've finished pushing the query to the server. Let's start
+ reading the results. */
+ self->async_status = ASYNC_READ;
res = PSYCO_POLL_READ;
break;
- case PGRES_POLLING_WRITING:
+ case 1: /* would block */
res = PSYCO_POLL_WRITE;
break;
- case PGRES_POLLING_FAILED:
- case PGRES_POLLING_ACTIVE:
+ case -1: /* error */
+ PyErr_SetString(OperationalError, PQerrorMessage(self->pgconn));
res = PSYCO_POLL_ERROR;
break;
}
break;
- case CONN_STATUS_READY:
- case CONN_STATUS_BEGIN:
- Dprintf("conn_poll: status = CONN_STATUS_READY/BEGIN");
- switch (self->async_status) {
- case ASYNC_READ:
- Dprintf("conn_poll: async_status = ASYNC_READ");
- if (0 == PQconsumeInput(self->pgconn)) {
- PyErr_SetString(OperationalError, PQerrorMessage(self->pgconn));
- res = PSYCO_POLL_ERROR;
- }
- if (PQisBusy(self->pgconn)) {
- res = PSYCO_POLL_READ;
- } else {
- /* Reading complete: set the async status so that a spare poll()
- will only look for NOTIFYs */
- self->async_status = ASYNC_DONE;
- res = PSYCO_POLL_OK;
- }
- break;
+ case ASYNC_READ:
+ Dprintf("conn_poll: async_status = ASYNC_READ");
+ if (0 == PQconsumeInput(self->pgconn)) {
+ PyErr_SetString(OperationalError, PQerrorMessage(self->pgconn));
+ res = PSYCO_POLL_ERROR;
+ }
+ if (PQisBusy(self->pgconn)) {
+ res = PSYCO_POLL_READ;
+ } else {
+ /* Reading complete: set the async status so that a spare poll()
+ will only look for NOTIFYs */
+ self->async_status = ASYNC_DONE;
+ res = PSYCO_POLL_OK;
+ }
+ break;
- case ASYNC_WRITE:
- Dprintf("conn_poll: async_status = ASYNC_WRITE");
- switch (PQflush(self->pgconn)) {
- case 0: /* success */
- /* we've finished pushing the query to the server. Let's start
- reading the results. */
- self->async_status = ASYNC_READ;
- res = PSYCO_POLL_READ;
- break;
- case 1: /* would block */
- res = PSYCO_POLL_WRITE;
- break;
- case -1: /* error */
- PyErr_SetString(OperationalError, PQerrorMessage(self->pgconn));
- res = PSYCO_POLL_ERROR;
- break;
- }
+ case ASYNC_DONE:
+ Dprintf("conn_poll: async_status = ASYNC_DONE");
+ /* We haven't asked anything: just check for notifications. */
+ switch (pq_is_busy(self)) {
+ case 0: /* will not block */
+ res = PSYCO_POLL_OK;
break;
-
- case ASYNC_DONE:
- Dprintf("conn_poll: async_status = ASYNC_DONE");
- /* We haven't asked anything: just check for notifications. */
- switch (pq_is_busy(self)) {
- case 0: /* will not block */
- res = PSYCO_POLL_OK;
- break;
- case 1: /* will block */
- res = PSYCO_POLL_READ;
- break;
- case -1: /* ouch, error */
- break;
- default:
- Dprintf("conn_poll: unexpected result from pq_is_busy");
- break;
- }
+ case 1: /* will block */
+ res = PSYCO_POLL_READ;
+ break;
+ case -1: /* ouch, error */
break;
-
default:
- Dprintf("conn_poll: in unexpected async status: %d",
- self->async_status);
- res = PSYCO_POLL_ERROR;
+ Dprintf("conn_poll: unexpected result from pq_is_busy");
+ break;
}
break;
default:
+ Dprintf("conn_poll: in unexpected async status: %d",
+ self->async_status);
+ res = PSYCO_POLL_ERROR;
+ }
+
+ return res;
+}
+
+
+/* conn_poll_green - poll a *sync* connection with external wait */
+
+PyObject *
+conn_poll_green(connectionObject *self)
+{
+ int res = PSYCO_POLL_ERROR;
+
+ switch (self->status) {
+ case CONN_STATUS_SETUP:
+ Dprintf("conn_poll: status = CONN_STATUS_SETUP");
+ self->status = CONN_STATUS_CONNECTING;
+ res = PSYCO_POLL_WRITE;
+ break;
+
+ case CONN_STATUS_CONNECTING:
+ Dprintf("conn_poll: status = CONN_STATUS_CONNECTING");
+ res = _conn_poll_connecting(self);
+ break;
+
+ case CONN_STATUS_READY:
+ case CONN_STATUS_BEGIN:
+ Dprintf("conn_poll: status = CONN_STATUS_READY/BEGIN");
+ res = _conn_poll_query(self);
+ break;
+
+ default:
Dprintf("conn_poll: in unexpected state");
res = PSYCO_POLL_ERROR;
}