aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/libpq/fe-connect.c38
-rw-r--r--src/interfaces/libpq/fe-misc.c3
-rw-r--r--src/interfaces/libpq/fe-protocol3.c4
-rw-r--r--src/interfaces/libpq/libpq-int.h2
4 files changed, 27 insertions, 20 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index a45f4cba34f..a570b81265d 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -391,9 +391,13 @@ pgthreadlock_t pg_g_threadlock = default_threadlock;
* Close any physical connection to the server, and reset associated
* state inside the connection object. We don't release state that
* would be needed to reconnect, though.
+ *
+ * We can always flush the output buffer, since there's no longer any hope
+ * of sending that data. However, unprocessed input data might still be
+ * valuable, so the caller must tell us whether to flush that or not.
*/
void
-pqDropConnection(PGconn *conn)
+pqDropConnection(PGconn *conn, bool flushInput)
{
/* Drop any SSL state */
pqsecure_close(conn);
@@ -401,8 +405,10 @@ pqDropConnection(PGconn *conn)
if (conn->sock != PGINVALID_SOCKET)
closesocket(conn->sock);
conn->sock = PGINVALID_SOCKET;
- /* Discard any unread/unsent data */
- conn->inStart = conn->inCursor = conn->inEnd = 0;
+ /* Optionally discard any unread data */
+ if (flushInput)
+ conn->inStart = conn->inCursor = conn->inEnd = 0;
+ /* Always discard any unsent data */
conn->outCount = 0;
}
@@ -1510,7 +1516,7 @@ connectDBStart(PGconn *conn)
return 1;
connect_errReturn:
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->status = CONNECTION_BAD;
return 0;
}
@@ -1732,7 +1738,7 @@ keep_going: /* We will come back to here until there is
{
if (!connectNoDelay(conn))
{
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->addr_cur = addr_cur->ai_next;
continue;
}
@@ -1742,7 +1748,7 @@ keep_going: /* We will come back to here until there is
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not set socket to nonblocking mode: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->addr_cur = addr_cur->ai_next;
continue;
}
@@ -1753,7 +1759,7 @@ keep_going: /* We will come back to here until there is
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->addr_cur = addr_cur->ai_next;
continue;
}
@@ -1800,7 +1806,7 @@ keep_going: /* We will come back to here until there is
if (err)
{
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->addr_cur = addr_cur->ai_next;
continue;
}
@@ -1887,7 +1893,7 @@ keep_going: /* We will come back to here until there is
* failure and keep going if there are more addresses.
*/
connectFailureMessage(conn, SOCK_ERRNO);
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
/*
* Try the next address, if any.
@@ -1932,7 +1938,7 @@ keep_going: /* We will come back to here until there is
* error message.
*/
connectFailureMessage(conn, optval);
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
/*
* If more addresses remain, keep trying, just as in the
@@ -2220,7 +2226,7 @@ keep_going: /* We will come back to here until there is
/* only retry once */
conn->allow_ssl_try = false;
/* Must drop the old connection */
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->status = CONNECTION_NEEDED;
goto keep_going;
}
@@ -2331,7 +2337,7 @@ keep_going: /* We will come back to here until there is
{
conn->pversion = PG_PROTOCOL(2, 0);
/* Must drop the old connection */
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->status = CONNECTION_NEEDED;
goto keep_going;
}
@@ -2397,7 +2403,7 @@ keep_going: /* We will come back to here until there is
/* only retry once */
conn->wait_ssl_try = false;
/* Must drop the old connection */
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->status = CONNECTION_NEEDED;
goto keep_going;
}
@@ -2413,7 +2419,7 @@ keep_going: /* We will come back to here until there is
/* only retry once */
conn->allow_ssl_try = false;
/* Must drop the old connection */
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->status = CONNECTION_NEEDED;
goto keep_going;
}
@@ -2574,7 +2580,7 @@ keep_going: /* We will come back to here until there is
PQclear(res);
conn->send_appname = false;
/* Must drop the old connection */
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->status = CONNECTION_NEEDED;
goto keep_going;
}
@@ -2970,7 +2976,7 @@ closePGconn(PGconn *conn)
/*
* Close the connection, reset all transient state, flush I/O buffers.
*/
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just
* absent */
conn->asyncStatus = PGASYNC_IDLE;
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index 0dbcf732227..b7b53d3a71c 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -815,7 +815,8 @@ definitelyEOF:
/* Come here if lower-level code already set a suitable errorMessage */
definitelyFailed:
- pqDropConnection(conn);
+ /* Do *not* drop any already-read data; caller still wants it */
+ pqDropConnection(conn, false);
conn->status = CONNECTION_BAD; /* No more connection to backend */
return -1;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index dbc0d89a4ed..c8bfca9eb01 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -446,8 +446,8 @@ handleSyncLoss(PGconn *conn, char id, int msgLength)
/* build an error result holding the error message */
pqSaveErrorResult(conn);
conn->asyncStatus = PGASYNC_READY; /* drop out of GetResult wait loop */
-
- pqDropConnection(conn);
+ /* flush input data since we're giving up on processing it */
+ pqDropConnection(conn, true);
conn->status = CONNECTION_BAD; /* No more connection to backend */
}
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 21759578f3a..f2f31b375f1 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -514,7 +514,7 @@ extern char *const pgresStatus[];
/* === in fe-connect.c === */
-extern void pqDropConnection(PGconn *conn);
+extern void pqDropConnection(PGconn *conn, bool flushInput);
extern int pqPacketSend(PGconn *conn, char pack_type,
const void *buf, size_t buf_len);
extern bool pqGetHomeDirectory(char *buf, int bufsize);