mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Back out old version and update with newer patch of:
Fix for non-blocking connections in libpq Bernhard Herzog
This commit is contained in:
parent
66cd6a0fb2
commit
6024ac1ba0
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.115 2002/03/05 05:20:12 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.116 2002/03/05 06:07:26 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.66 2002/03/05 05:20:12 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.67 2002/03/05 06:07:26 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -110,21 +110,19 @@ pqPutc(char c, PGconn *conn)
|
|||||||
static int
|
static int
|
||||||
pqPutBytes(const char *s, size_t nbytes, PGconn *conn)
|
pqPutBytes(const char *s, size_t nbytes, PGconn *conn)
|
||||||
{
|
{
|
||||||
/*
|
/* Strategy to handle blocking and non-blocking connections: Fill
|
||||||
* Strategy to handle blocking and non-blocking connections: Fill the
|
* the output buffer and flush it repeatedly until either all data
|
||||||
* output buffer and flush it repeatedly until either all data has
|
* has been sent or is at least queued in the buffer.
|
||||||
* been sent or is at least queued in the buffer.
|
|
||||||
*
|
*
|
||||||
* For non-blocking connections, grow the buffer if not all data fits
|
* For non-blocking connections, grow the buffer if not all data
|
||||||
* into it and the buffer can't be sent because the socket would
|
* fits into it and the buffer can't be sent because the socket
|
||||||
* block.
|
* would block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (nbytes)
|
while (nbytes)
|
||||||
{
|
{
|
||||||
size_t avail,
|
size_t avail, remaining;
|
||||||
remaining;
|
|
||||||
|
|
||||||
/* fill the output buffer */
|
/* fill the output buffer */
|
||||||
avail = Max(conn->outBufSize - conn->outCount, 0);
|
avail = Max(conn->outBufSize - conn->outCount, 0);
|
||||||
remaining = Min(avail, nbytes);
|
remaining = Min(avail, nbytes);
|
||||||
@ -133,40 +131,36 @@ pqPutBytes(const char *s, size_t nbytes, PGconn *conn)
|
|||||||
s += remaining;
|
s += remaining;
|
||||||
nbytes -= remaining;
|
nbytes -= remaining;
|
||||||
|
|
||||||
/*
|
/* if the data didn't fit completely into the buffer, try to
|
||||||
* if the data didn't fit completely into the buffer, try to flush
|
* flush the buffer */
|
||||||
* the buffer
|
|
||||||
*/
|
|
||||||
if (nbytes)
|
if (nbytes)
|
||||||
{
|
{
|
||||||
int send_result = pqSendSome(conn);
|
int send_result = pqSendSome(conn);
|
||||||
|
|
||||||
/* if there were errors, report them */
|
/* if there were errors, report them */
|
||||||
if (send_result < 0)
|
if (send_result < 0)
|
||||||
return EOF;
|
return EOF;
|
||||||
|
|
||||||
/*
|
/* if not all data could be sent, increase the output
|
||||||
* if not all data could be sent, increase the output buffer,
|
* buffer, put the rest of s into it and return
|
||||||
* put the rest of s into it and return successfully. This
|
* successfully. This case will only happen in a
|
||||||
* case will only happen in a non-blocking connection
|
* non-blocking connection
|
||||||
*/
|
*/
|
||||||
if (send_result > 0)
|
if (send_result > 0)
|
||||||
{
|
{
|
||||||
/*
|
/* try to grow the buffer.
|
||||||
* try to grow the buffer. FIXME: The new size could be
|
* FIXME: The new size could be chosen more
|
||||||
* chosen more intelligently.
|
* intelligently.
|
||||||
*/
|
*/
|
||||||
size_t buflen = conn->outCount + nbytes;
|
size_t buflen = conn->outCount + nbytes;
|
||||||
|
|
||||||
if (buflen > conn->outBufSize)
|
if (buflen > conn->outBufSize)
|
||||||
{
|
{
|
||||||
char *newbuf = realloc(conn->outBuffer, buflen);
|
char * newbuf = realloc(conn->outBuffer, buflen);
|
||||||
|
|
||||||
if (!newbuf)
|
if (!newbuf)
|
||||||
{
|
{
|
||||||
/* realloc failed. Probably out of memory */
|
/* realloc failed. Probably out of memory */
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
"cannot allocate memory for output buffer\n");
|
"cannot allocate memory for output buffer\n");
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
conn->outBuffer = newbuf;
|
conn->outBuffer = newbuf;
|
||||||
@ -181,11 +175,9 @@ pqPutBytes(const char *s, size_t nbytes, PGconn *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* pqSendSome was able to send all data. Continue with the next
|
||||||
* pqSendSome was able to send all data. Continue with the next
|
* chunk of s. */
|
||||||
* chunk of s.
|
} /* while */
|
||||||
*/
|
|
||||||
} /* while */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -631,19 +623,11 @@ definitelyFailed:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pqSendSome: send any data waiting in the output buffer and return 0
|
/*
|
||||||
* if all data was sent, -1 if an error occurred or 1 if not all data
|
* pqSendSome: send any data waiting in the output buffer.
|
||||||
* could be written because the socket would have blocked.
|
|
||||||
*
|
*
|
||||||
* For a blocking connection all data will be sent unless an error
|
* Return 0 on sucess, -1 on failure and 1 when data remains because the
|
||||||
* occurrs. -1 will only be returned if the connection is non-blocking.
|
* socket would block and the connection is non-blocking.
|
||||||
*
|
|
||||||
* Internally, the case of data remaining in the buffer after pqSendSome
|
|
||||||
* could be determined by looking at outCount, but this function also
|
|
||||||
* serves as the implementation of the new API function PQsendsome.
|
|
||||||
*
|
|
||||||
* FIXME: perhaps it would be more useful to return the number of bytes
|
|
||||||
* remaining?
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pqSendSome(PGconn *conn)
|
pqSendSome(PGconn *conn)
|
||||||
@ -655,7 +639,7 @@ pqSendSome(PGconn *conn)
|
|||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("connection not open\n"));
|
libpq_gettext("connection not open\n"));
|
||||||
return EOF;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -713,7 +697,7 @@ pqSendSome(PGconn *conn)
|
|||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext(
|
libpq_gettext(
|
||||||
"server closed the connection unexpectedly\n"
|
"server closed the connection unexpectedly\n"
|
||||||
"\tThis probably means the server terminated abnormally\n"
|
"\tThis probably means the server terminated abnormally\n"
|
||||||
"\tbefore or while processing the request.\n"));
|
"\tbefore or while processing the request.\n"));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -778,6 +762,7 @@ pqSendSome(PGconn *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pqFlush: send any data waiting in the output buffer
|
* pqFlush: send any data waiting in the output buffer
|
||||||
*
|
*
|
||||||
@ -790,7 +775,9 @@ int
|
|||||||
pqFlush(PGconn *conn)
|
pqFlush(PGconn *conn)
|
||||||
{
|
{
|
||||||
if (pqSendSome(conn))
|
if (pqSendSome(conn))
|
||||||
|
{
|
||||||
return EOF;
|
return EOF;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,7 +799,7 @@ pqWait(int forRead, int forWrite, PGconn *conn)
|
|||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("connection not open\n"));
|
libpq_gettext("connection not open\n"));
|
||||||
return -1;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forRead || forWrite)
|
if (forRead || forWrite)
|
||||||
@ -913,20 +900,19 @@ libpq_gettext(const char *msgid)
|
|||||||
* strerror replacement for windows:
|
* strerror replacement for windows:
|
||||||
*
|
*
|
||||||
* This works on WIN2000 and newer, but we don't know where to find WinSock
|
* This works on WIN2000 and newer, but we don't know where to find WinSock
|
||||||
* error strings on older Windows flavors. If you know, clue us in.
|
* error strings on older Windows flavors. If you know, clue us in.
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
winsock_strerror(int eno)
|
winsock_strerror(int eno)
|
||||||
{
|
{
|
||||||
static char err_buf[512];
|
static char err_buf[512];
|
||||||
|
#define WSSE_MAXLEN (sizeof(err_buf)-1-13) /* 13 for " (0x00000000)" */
|
||||||
#define WSSE_MAXLEN (sizeof(err_buf)-1-13) /* 13 for " (0x00000000)" */
|
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
/* First try the "system table", this works on Win2k and up */
|
/* First try the "system table", this works on Win2k and up */
|
||||||
|
|
||||||
if (FormatMessage(
|
if (FormatMessage(
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
|
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||||
0,
|
0,
|
||||||
eno,
|
eno,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: libpq-fe.h,v 1.82 2002/03/05 05:20:12 momjian Exp $
|
* $Id: libpq-fe.h,v 1.83 2002/03/05 06:07:26 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -282,10 +282,6 @@ extern int PQisnonblocking(const PGconn *conn);
|
|||||||
|
|
||||||
/* Force the write buffer to be written (or at least try) */
|
/* Force the write buffer to be written (or at least try) */
|
||||||
extern int PQflush(PGconn *conn);
|
extern int PQflush(PGconn *conn);
|
||||||
/*
|
|
||||||
* Force the write buffer to be written (or at least try)
|
|
||||||
* (better than PQflush)
|
|
||||||
*/
|
|
||||||
extern int PQsendSome(PGconn *conn);
|
extern int PQsendSome(PGconn *conn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: libpq-int.h,v 1.45 2002/03/05 05:20:12 momjian Exp $
|
* $Id: libpq-int.h,v 1.46 2002/03/05 06:07:27 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user