* 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);
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;
}
return 1;
connect_errReturn:
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->status = CONNECTION_BAD;
return 0;
}
{
if (!connectNoDelay(conn))
{
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->addr_cur = addr_cur->ai_next;
continue;
}
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;
}
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;
}
if (err)
{
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->addr_cur = addr_cur->ai_next;
continue;
}
* failure and keep going if there are more addresses.
*/
connectFailureMessage(conn, SOCK_ERRNO);
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
/*
* Try the next address, if any.
* error message.
*/
connectFailureMessage(conn, optval);
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
/*
* If more addresses remain, keep trying, just as in the
/* 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;
}
{
conn->pversion = PG_PROTOCOL(2, 0);
/* Must drop the old connection */
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->status = CONNECTION_NEEDED;
goto keep_going;
}
/* 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;
}
/* 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;
}
PQclear(res);
conn->send_appname = false;
/* Must drop the old connection */
- pqDropConnection(conn);
+ pqDropConnection(conn, true);
conn->status = CONNECTION_NEEDED;
goto keep_going;
}
/*
* 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;