PQconnectStart() and -EINTR

Started by David Fordover 24 years ago3 messageshackers
Jump to latest
#1David Ford
david@blue-labs.org

I've got a bit of a problem. I added a fast SIGALRM handler in my
project to do various maintenance and this broke PQconnectStart().

Oct 23 21:56:36 james BlueList: connectDBStart() -- connect() failed:
Interrupted system call ^IIs the postmaster running (with -i) at
'archives.blue-labs.org' ^Iand accepting connections on TCP/IP port 5432?

PQstatus() returns CONNECTION_BAD, how can I reenter the connection
cycle or delay, more like, how do I differentiate between an actual
failure to connect and an interruption by signal? My alarm timer
happens much too frequently for this code to make a connection and
unfortunately I can't disable the alarm because it's used for bean
counting and other maintenance.

Thanks,
David

Code snippet:

...
/*
* play some tricks now, use async connect mode to find if the server
* is alive. once we've figured that out, disconnect and immediately
* reconnect in blocking mode. this mitigates the annoying hangs from
* using PQconnectdb which has no support for a timeout.
*/
conn=PQconnectStart(cstr);
if(!conn) {
dlog(_LOG_debug, "SQL conn is NULL, aborting");
return NULL;
}

do {
c++;
pgstat=PQstatus(conn);
switch (pgstat) {
case CONNECTION_STARTED:
dlog(_LOG_debug, "Connecting to SQL server...");
break;
case CONNECTION_MADE:
case CONNECTION_OK:
dlog(_LOG_debug, "Connected to SQL server in asynchronous
mode...");
break;
case CONNECTION_BAD:
dlog(_LOG_debug, PQerrorMessage(conn));
if(conn)
PQfinish(conn);
dlog(_LOG_warning, "failed to connect to server");
return NULL;
break;
default:
dlog(_LOG_debug, "pg conx state = %i", pgstat);
break;
}

if(pgstat==CONNECTION_MADE||CONNECTION_OK)
break;

if(c>15) {
if(conn)
PQfinish(conn);
dlog(_LOG_warning, "failed to connect to server, timed out");
return NULL;
}

req.tv_sec=1;
req.tv_nsec=0;
sleep(&req);

} while(1);

/*
* close it and reopen it in normal blocking mode
*/
PQfinish(conn);
conn=PQconnectdb(cstr);
...

#2Doug McNaught
doug@wireboard.com
In reply to: David Ford (#1)
Re: PQconnectStart() and -EINTR

David Ford <david@blue-labs.org> writes:

I've got a bit of a problem. I added a fast SIGALRM handler in my project to
do various maintenance and this broke PQconnectStart().

Oct 23 21:56:36 james BlueList: connectDBStart() -- connect() failed:
Interrupted system call ^IIs the postmaster running (with -i) at
'archives.blue-labs.org' ^Iand accepting connections on TCP/IP port 5432?

PQstatus() returns CONNECTION_BAD, how can I reenter the connection cycle or
delay, more like, how do I differentiate between an actual failure to connect
and an interruption by signal? My alarm timer happens much too frequently for
this code to make a connection and unfortunately I can't disable the alarm
because it's used for bean counting and other maintenance.

Sounds like something in libpq needs to check for EINTR and reissue the
connect() call (or select()/poll() if it's a nonblocking connect()).

-Doug
--
Let us cross over the river, and rest under the shade of the trees.
--T. J. Jackson, 1863

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: David Ford (#1)
Re: PQconnectStart() and -EINTR

David Ford <david@blue-labs.org> writes:

I've got a bit of a problem. I added a fast SIGALRM handler in my
project to do various maintenance and this broke PQconnectStart().

It'd probably be reasonable to just retry the connect() call if it
fails with EINTR. If that works for you, send a patch...

regards, tom lane