Sigh, I'm an idiot ... I broke the async startup logic a couple days ago,

by creating a race condition.  It wasn't waiting for select() to say
write-ready immediately after connect, which meant that you might get
an unhelpful 'broken pipe' error message if connect failed, rather than
the intended error message.
This commit is contained in:
Tom Lane 2000-01-16 21:18:52 +00:00
parent fdc85f50a3
commit d00391e7ac
1 changed files with 28 additions and 7 deletions

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.110 2000/01/15 05:37:21 ishii Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.111 2000/01/16 21:18:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -931,10 +931,16 @@ connect_errReturn:
static int static int
connectDBComplete(PGconn *conn) connectDBComplete(PGconn *conn)
{ {
PostgresPollingStatusType flag; PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
if (conn == NULL || conn->status == CONNECTION_BAD)
return 0;
for (;;) { for (;;) {
flag = PQconnectPoll(conn); /*
* Wait, if necessary. Note that the initial state (just after
* PQconnectStart) is to wait for the socket to select for writing.
*/
switch (flag) switch (flag)
{ {
case PGRES_POLLING_ACTIVE: case PGRES_POLLING_ACTIVE:
@ -964,6 +970,10 @@ connectDBComplete(PGconn *conn)
conn->status = CONNECTION_BAD; conn->status = CONNECTION_BAD;
return 0; return 0;
} }
/*
* Now try to advance the state machine.
*/
flag = PQconnectPoll(conn);
} }
} }
@ -1347,12 +1357,16 @@ error_return:
* Starts the process of passing the values of a standard set of environment * Starts the process of passing the values of a standard set of environment
* variables to the backend. * variables to the backend.
* *
* ---------------- */ * ----------------
*/
PGsetenvHandle PGsetenvHandle
PQsetenvStart(PGconn *conn) PQsetenvStart(PGconn *conn)
{ {
struct pg_setenv_state *handle; struct pg_setenv_state *handle;
if (conn == NULL || conn->status == CONNECTION_BAD)
return NULL;
if ((handle = malloc(sizeof(struct pg_setenv_state))) == NULL) if ((handle = malloc(sizeof(struct pg_setenv_state))) == NULL)
{ {
printfPQExpBuffer(&conn->errorMessage, printfPQExpBuffer(&conn->errorMessage,
@ -1621,13 +1635,16 @@ int
PQsetenv(PGconn *conn) PQsetenv(PGconn *conn)
{ {
PGsetenvHandle handle; PGsetenvHandle handle;
PostgresPollingStatusType flag; PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
if ((handle = PQsetenvStart(conn)) == NULL) if ((handle = PQsetenvStart(conn)) == NULL)
return 0; return 0;
for (;;) { for (;;) {
flag = PQsetenvPoll(conn); /*
* Wait, if necessary. Note that the initial state (just after
* PQsetenvStart) is to wait for the socket to select for writing.
*/
switch (flag) switch (flag)
{ {
case PGRES_POLLING_ACTIVE: case PGRES_POLLING_ACTIVE:
@ -1653,10 +1670,14 @@ PQsetenv(PGconn *conn)
break; break;
default: default:
/* Just in case we failed to set it in PQconnectPoll */ /* Just in case we failed to set it in PQsetenvPoll */
conn->status = CONNECTION_BAD; conn->status = CONNECTION_BAD;
return 0; return 0;
} }
/*
* Now try to advance the state machine.
*/
flag = PQsetenvPoll(conn);
} }
} }