Fix for EINTR returns from Win9X socket operations:
In summary, if a software writer implements timer events or other events which generate a signal with a timing fast enough to occur while libpq is inside connect(), then connect returns -EINTR. The code following the connect call does not handle this and generates an error message. The sum result is that the pg_connect() fails. If the timer or other event is right on the window of the connect() completion time, the pg_connect() may appear to work sporadically. If the event is too slow, pg_connect() will appear to always work and if the event is too fast, pg_connect() will always fail. David Ford
This commit is contained in:
parent
b66cbc1fa2
commit
394eec1068
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.182 2002/03/02 00:49:22 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.183 2002/04/15 23:34:17 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -913,8 +913,13 @@ connectDBStart(PGconn *conn)
|
||||||
* Thus, we have to make arrangements for all eventualities.
|
* Thus, we have to make arrangements for all eventualities.
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
|
retry1:
|
||||||
if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
|
if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
|
||||||
{
|
{
|
||||||
|
if (SOCK_ERRNO == EINTR)
|
||||||
|
/* Interrupted system call - we'll just try again */
|
||||||
|
goto retry1;
|
||||||
|
|
||||||
if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || SOCK_ERRNO == 0)
|
if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || SOCK_ERRNO == 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -949,9 +954,14 @@ connectDBStart(PGconn *conn)
|
||||||
SOCK_STRERROR(SOCK_ERRNO));
|
SOCK_STRERROR(SOCK_ERRNO));
|
||||||
goto connect_errReturn;
|
goto connect_errReturn;
|
||||||
}
|
}
|
||||||
|
retry2:
|
||||||
/* Now receive the postmasters response */
|
/* Now receive the postmasters response */
|
||||||
if (recv(conn->sock, &SSLok, 1, 0) != 1)
|
if (recv(conn->sock, &SSLok, 1, 0) != 1)
|
||||||
{
|
{
|
||||||
|
if (SOCK_ERRNO == EINTR)
|
||||||
|
/* Interrupted system call - we'll just try again */
|
||||||
|
goto retry2;
|
||||||
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("could not receive server response to SSL negotiation packet: %s\n"),
|
libpq_gettext("could not receive server response to SSL negotiation packet: %s\n"),
|
||||||
SOCK_STRERROR(SOCK_ERRNO));
|
SOCK_STRERROR(SOCK_ERRNO));
|
||||||
|
@ -2132,8 +2142,12 @@ PQrequestCancel(PGconn *conn)
|
||||||
"PQrequestCancel() -- socket() failed: ");
|
"PQrequestCancel() -- socket() failed: ");
|
||||||
goto cancel_errReturn;
|
goto cancel_errReturn;
|
||||||
}
|
}
|
||||||
|
retry3:
|
||||||
if (connect(tmpsock, &conn->raddr.sa, conn->raddr_len) < 0)
|
if (connect(tmpsock, &conn->raddr.sa, conn->raddr_len) < 0)
|
||||||
{
|
{
|
||||||
|
if (SOCK_ERRNO == EINTR)
|
||||||
|
/* Interrupted system call - we'll just try again */
|
||||||
|
goto retry3;
|
||||||
strcpy(conn->errorMessage.data,
|
strcpy(conn->errorMessage.data,
|
||||||
"PQrequestCancel() -- connect() failed: ");
|
"PQrequestCancel() -- connect() failed: ");
|
||||||
goto cancel_errReturn;
|
goto cancel_errReturn;
|
||||||
|
@ -2150,8 +2164,12 @@ PQrequestCancel(PGconn *conn)
|
||||||
crp.cp.backendPID = htonl(conn->be_pid);
|
crp.cp.backendPID = htonl(conn->be_pid);
|
||||||
crp.cp.cancelAuthCode = htonl(conn->be_key);
|
crp.cp.cancelAuthCode = htonl(conn->be_key);
|
||||||
|
|
||||||
|
retry4:
|
||||||
if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
|
if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
|
||||||
{
|
{
|
||||||
|
if (SOCK_ERRNO == EINTR)
|
||||||
|
/* Interrupted system call - we'll just try again */
|
||||||
|
goto retry4;
|
||||||
strcpy(conn->errorMessage.data,
|
strcpy(conn->errorMessage.data,
|
||||||
"PQrequestCancel() -- send() failed: ");
|
"PQrequestCancel() -- send() failed: ");
|
||||||
goto cancel_errReturn;
|
goto cancel_errReturn;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.68 2002/03/06 06:10:42 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.69 2002/04/15 23:34:17 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -361,7 +361,7 @@ pqReadReady(PGconn *conn)
|
||||||
if (!conn || conn->sock < 0)
|
if (!conn || conn->sock < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
retry:
|
retry1:
|
||||||
FD_ZERO(&input_mask);
|
FD_ZERO(&input_mask);
|
||||||
FD_SET(conn->sock, &input_mask);
|
FD_SET(conn->sock, &input_mask);
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
|
@ -371,7 +371,7 @@ retry:
|
||||||
{
|
{
|
||||||
if (SOCK_ERRNO == EINTR)
|
if (SOCK_ERRNO == EINTR)
|
||||||
/* Interrupted system call - we'll just try again */
|
/* Interrupted system call - we'll just try again */
|
||||||
goto retry;
|
goto retry1;
|
||||||
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("select() failed: %s\n"),
|
libpq_gettext("select() failed: %s\n"),
|
||||||
|
@ -395,7 +395,7 @@ pqWriteReady(PGconn *conn)
|
||||||
if (!conn || conn->sock < 0)
|
if (!conn || conn->sock < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
retry:
|
retry2:
|
||||||
FD_ZERO(&input_mask);
|
FD_ZERO(&input_mask);
|
||||||
FD_SET(conn->sock, &input_mask);
|
FD_SET(conn->sock, &input_mask);
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
|
@ -405,7 +405,7 @@ retry:
|
||||||
{
|
{
|
||||||
if (SOCK_ERRNO == EINTR)
|
if (SOCK_ERRNO == EINTR)
|
||||||
/* Interrupted system call - we'll just try again */
|
/* Interrupted system call - we'll just try again */
|
||||||
goto retry;
|
goto retry2;
|
||||||
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("select() failed: %s\n"),
|
libpq_gettext("select() failed: %s\n"),
|
||||||
|
@ -478,7 +478,7 @@ pqReadData(PGconn *conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OK, try to read some data */
|
/* OK, try to read some data */
|
||||||
tryAgain:
|
retry3:
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
if (conn->ssl)
|
if (conn->ssl)
|
||||||
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
|
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
|
||||||
|
@ -490,7 +490,7 @@ tryAgain:
|
||||||
if (nread < 0)
|
if (nread < 0)
|
||||||
{
|
{
|
||||||
if (SOCK_ERRNO == EINTR)
|
if (SOCK_ERRNO == EINTR)
|
||||||
goto tryAgain;
|
goto retry3;
|
||||||
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
|
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
|
||||||
#ifdef EAGAIN
|
#ifdef EAGAIN
|
||||||
if (SOCK_ERRNO == EAGAIN)
|
if (SOCK_ERRNO == EAGAIN)
|
||||||
|
@ -531,7 +531,7 @@ tryAgain:
|
||||||
(conn->inBufSize - conn->inEnd) >= 8192)
|
(conn->inBufSize - conn->inEnd) >= 8192)
|
||||||
{
|
{
|
||||||
someread = 1;
|
someread = 1;
|
||||||
goto tryAgain;
|
goto retry3;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -564,7 +564,7 @@ tryAgain:
|
||||||
* Still not sure that it's EOF, because some data could have just
|
* Still not sure that it's EOF, because some data could have just
|
||||||
* arrived.
|
* arrived.
|
||||||
*/
|
*/
|
||||||
tryAgain2:
|
retry4:
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
if (conn->ssl)
|
if (conn->ssl)
|
||||||
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
|
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
|
||||||
|
@ -576,7 +576,7 @@ tryAgain2:
|
||||||
if (nread < 0)
|
if (nread < 0)
|
||||||
{
|
{
|
||||||
if (SOCK_ERRNO == EINTR)
|
if (SOCK_ERRNO == EINTR)
|
||||||
goto tryAgain2;
|
goto retry4;
|
||||||
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
|
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
|
||||||
#ifdef EAGAIN
|
#ifdef EAGAIN
|
||||||
if (SOCK_ERRNO == EAGAIN)
|
if (SOCK_ERRNO == EAGAIN)
|
||||||
|
@ -804,7 +804,7 @@ pqWait(int forRead, int forWrite, PGconn *conn)
|
||||||
|
|
||||||
if (forRead || forWrite)
|
if (forRead || forWrite)
|
||||||
{
|
{
|
||||||
retry:
|
retry5:
|
||||||
FD_ZERO(&input_mask);
|
FD_ZERO(&input_mask);
|
||||||
FD_ZERO(&output_mask);
|
FD_ZERO(&output_mask);
|
||||||
FD_ZERO(&except_mask);
|
FD_ZERO(&except_mask);
|
||||||
|
@ -817,7 +817,7 @@ retry:
|
||||||
(struct timeval *) NULL) < 0)
|
(struct timeval *) NULL) < 0)
|
||||||
{
|
{
|
||||||
if (SOCK_ERRNO == EINTR)
|
if (SOCK_ERRNO == EINTR)
|
||||||
goto retry;
|
goto retry5;
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("select() failed: %s\n"),
|
libpq_gettext("select() failed: %s\n"),
|
||||||
SOCK_STRERROR(SOCK_ERRNO));
|
SOCK_STRERROR(SOCK_ERRNO));
|
||||||
|
|
Loading…
Reference in New Issue