Add NonblockingForgetResults().

This is very similar to ForgetResults() except that no network IO is
performed. Primarily useful in error handling cases.
pull/1650/head
Andres Freund 2017-06-30 18:20:54 -07:00 committed by Metin Doslu
parent c8f7c7fc59
commit 25cabe634e
2 changed files with 71 additions and 2 deletions

View File

@ -46,8 +46,8 @@ IsResponseOK(PGresult *result)
/*
* ForgetResults clears a connection from pending activity.
*
* XXX: In the future it might be a good idea to use use PQcancel() if results
* would require network IO.
* Note that this might require network IO. If that's not acceptable, use
* NonblockingForgetResults().
*/
void
ForgetResults(MultiConnection *connection)
@ -73,6 +73,74 @@ ForgetResults(MultiConnection *connection)
}
/*
* NonblockingForgetResults clears a connection from pending activity if doing
* so does not require network IO. Returns true if successful, false
* otherwise.
*/
bool
NonblockingForgetResults(MultiConnection *connection)
{
PGconn *pgConn = connection->pgConn;
if (PQstatus(pgConn) != CONNECTION_OK)
{
return false;
}
Assert(PQisnonblocking(pgConn));
while (true)
{
PGresult *result = NULL;
/* just in case there's a lot of results */
CHECK_FOR_INTERRUPTS();
/*
* If busy, there might still be results already received and buffered
* by the OS. As connection is in non-blocking mode, we can check for
* that without blocking.
*/
if (PQisBusy(pgConn))
{
if (PQflush(pgConn) == -1)
{
/* write failed */
return false;
}
if (PQconsumeInput(pgConn) == 0)
{
/* some low-level failure */
return false;
}
}
/* clearing would require blocking IO, return */
if (PQisBusy(pgConn))
{
return false;
}
result = PQgetResult(pgConn);
if (PQresultStatus(result) == PGRES_COPY_IN)
{
/* in copy, can't reliably recover without blocking */
return false;
}
if (result == NULL)
{
return true;
}
PQclear(result);
}
pg_unreachable();
}
/*
* SqlStateMatchesCategory returns true if the given sql state (which may be
* NULL if unknown) is in the given error category. Note that we use

View File

@ -26,6 +26,7 @@ extern bool LogRemoteCommands;
/* simple helpers */
extern bool IsResponseOK(struct pg_result *result);
extern void ForgetResults(MultiConnection *connection);
extern bool NonblockingForgetResults(MultiConnection *connection);
extern bool SqlStateMatchesCategory(char *sqlStateString, int category);
/* report errors & warnings */