fixing wait_connection_availability()

wait_connection_availability() did take at least 2 seconds per call in
the old incarnation. Now we may finish a call without any sleep at all
when the result is already ready at the time called
This commit is contained in:
Christian Kruse
2014-02-15 01:31:12 +01:00
parent d58fd080ca
commit 18f1fed77f
2 changed files with 43 additions and 12 deletions

View File

@@ -18,6 +18,7 @@
*/ */
#include <unistd.h> #include <unistd.h>
#include <time.h>
#include "repmgr.h" #include "repmgr.h"
#include "strutil.h" #include "strutil.h"
@@ -426,11 +427,17 @@ getMasterConnection(PGconn *standby_conn, char *schema, char *cluster,
* return 1 if Ok; 0 if any error ocurred; -1 if timeout reached * return 1 if Ok; 0 if any error ocurred; -1 if timeout reached
*/ */
int int
wait_connection_availability(PGconn *conn, int timeout) wait_connection_availability(PGconn *conn, unsigned long timeout)
{ {
PGresult *res; PGresult *res;
fd_set read_set;
int sock = PQsocket(conn);
struct timeval tmout, before, after;
while(timeout-- >= 0) /* recalc to microseconds */
timeout *= 1000000;
while (timeout > 0)
{ {
if (PQconsumeInput(conn) == 0) if (PQconsumeInput(conn) == 0)
{ {
@@ -441,19 +448,43 @@ wait_connection_availability(PGconn *conn, int timeout)
if (PQisBusy(conn) == 0) if (PQisBusy(conn) == 0)
{ {
do {
res = PQgetResult(conn); res = PQgetResult(conn);
if (res == NULL)
break;
PQclear(res); PQclear(res);
} while(res != NULL);
break;
} }
sleep(1);
}
if (timeout >= 0) tmout.tv_sec = 0;
return 1; tmout.tv_usec = 250000;
else {
log_warning(_("wait_connection_availability: timeout reached")); FD_ZERO(&read_set);
FD_SET(sock, &read_set);
gettimeofday(&before);
if (select(sock, &read_set, NULL, NULL, &tmout) == -1)
{
log_warning(
_("wait_connection_availability: select() returned with error: %s"),
strerror(errno));
return -1; return -1;
} }
gettimeofday(&after);
timeout -= (after.tv_sec * 1000000 + after.tv_usec) -
(before.tv_sec * 1000000 + before.tv_usec);
}
if (timeout >= 0)
{
return 1;
}
log_warning(_("wait_connection_availability: timeout reached"));
return -1;
} }

View File

@@ -39,6 +39,6 @@ const char *get_cluster_size(PGconn *conn);
PGconn *getMasterConnection(PGconn *standby_conn, char *schema, char *cluster, PGconn *getMasterConnection(PGconn *standby_conn, char *schema, char *cluster,
int *master_id, char *master_conninfo_out); int *master_id, char *master_conninfo_out);
int wait_connection_availability(PGconn *conn, int timeout); int wait_connection_availability(PGconn *conn, unsigned long timeout);
bool CancelQuery(PGconn *conn, int timeout); bool CancelQuery(PGconn *conn, int timeout);
#endif #endif