diff options
author | Bruce Momjian <bruce@momjian.us> | 2000-01-18 06:09:24 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2000-01-18 06:09:24 +0000 |
commit | 10d7287ab927214607e34bae1c4a0f7bad79a4aa (patch) | |
tree | 68c1bbaf6023f284fefd4762b00eac1a2c1bd42f /src/interfaces/libpq/fe-misc.c | |
parent | b1e891dbd46147359ac50fa58b07d114f5e29601 (diff) | |
download | postgresql-10d7287ab927214607e34bae1c4a0f7bad79a4aa.tar.gz postgresql-10d7287ab927214607e34bae1c4a0f7bad79a4aa.zip |
Libpq non-blocking mode, from Alfred Perlstein
Diffstat (limited to 'src/interfaces/libpq/fe-misc.c')
-rw-r--r-- | src/interfaces/libpq/fe-misc.c | 68 |
1 files changed, 64 insertions, 4 deletions
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 89425e0034c..a936e937427 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -24,7 +24,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.33 1999/11/30 03:08:19 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.34 2000/01/18 06:09:24 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -86,6 +86,37 @@ pqPutBytes(const char *s, size_t nbytes, PGconn *conn) { size_t avail = Max(conn->outBufSize - conn->outCount, 0); + /* + * if we are non-blocking and the send queue is too full to buffer this + * request then try to flush some and return an error + */ + if (pqIsnonblocking(conn) && nbytes > avail && pqFlush(conn)) + { + /* + * even if the flush failed we may still have written some + * data, recalculate the size of the send-queue relative + * to the amount we have to send, we may be able to queue it + * afterall even though it's not sent to the database it's + * ok, any routines that check the data coming from the + * database better call pqFlush() anyway. + */ + if (nbytes > Max(conn->outBufSize - conn->outCount, 0)) + { + printfPQExpBuffer(&conn->errorMessage, + "pqPutBytes -- pqFlush couldn't flush enough" + " data: space available: %d, space needed %d\n", + Max(conn->outBufSize - conn->outCount, 0), nbytes); + return EOF; + } + } + + /* + * is the amount of data to be sent is larger than the size of the + * output buffer then we must flush it to make more room. + * + * the code above will make sure the loop conditional is never + * true for non-blocking connections + */ while (nbytes > avail) { memcpy(conn->outBuffer + conn->outCount, s, avail); @@ -548,6 +579,14 @@ pqFlush(PGconn *conn) return EOF; } + /* + * don't try to send zero data, allows us to use this function + * without too much worry about overhead + */ + if (len == 0) + return (0); + + /* while there's still data to send */ while (len > 0) { /* Prevent being SIGPIPEd if backend has closed the connection. */ @@ -556,6 +595,7 @@ pqFlush(PGconn *conn) #endif int sent; + #ifdef USE_SSL if (conn->ssl) sent = SSL_write(conn->ssl, ptr, len); @@ -585,6 +625,8 @@ pqFlush(PGconn *conn) case EWOULDBLOCK: break; #endif + case EINTR: + continue; case EPIPE: #ifdef ECONNRESET @@ -616,13 +658,31 @@ pqFlush(PGconn *conn) ptr += sent; len -= sent; } + if (len > 0) { /* We didn't send it all, wait till we can send more */ - /* At first glance this looks as though it should block. I think - * that it will be OK though, as long as the socket is - * non-blocking. */ + /* + * if the socket is in non-blocking mode we may need + * to abort here + */ +#ifdef USE_SSL + /* can't do anything for our SSL users yet */ + if (conn->ssl == NULL) + { +#endif + if (pqIsnonblocking(conn)) + { + /* shift the contents of the buffer */ + memmove(conn->outBuffer, ptr, len); + conn->outCount = len; + return EOF; + } +#ifdef USE_SSL + } +#endif + if (pqWait(FALSE, TRUE, conn)) return EOF; } |