Thread: PQconnectStart() and -EINTR

PQconnectStart() and -EINTR

From
David Ford
Date:
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
PQconnectdbwhich has no support for a timeout.   */  conn=PQconnectStart(cstr);  if(!conn) {     dlog(_LOG_debug, "SQL
connis NULL, aborting");     return NULL;  }    do {     c++;     pgstat=PQstatus(conn);     switch (pgstat) {
caseCONNECTION_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
innormal blocking mode   */  PQfinish(conn);  conn=PQconnectdb(cstr);
 
...




Re: PQconnectStart() and -EINTR

From
Doug McNaught
Date:
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


Re: PQconnectStart() and -EINTR

From
Tom Lane
Date:
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