select + PQnotifies - Mailing list pgsql-general

From James Leigh
Subject select + PQnotifies
Date
Msg-id 1012585788.29393.39.camel@jacob
Whole thread Raw
Responses Re: select + PQnotifies  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-general
I have been having some trouble with using PQnotifies and the select
function.  When I run the program below, the select function returns
early (before 5sec) when I send it a notify; but once the select
function runs out the first time (after 5sec), then no matter how many
time I send anotify the select does not return until after the full 5
secs.
----
$ gcc -o testlibpq testlibpq.c -lpq -I/usr/include/postgresql
$ DBHOST=db DB=gpdb ./testlibpq
Calling select(4,&rfds(3),NULL,NULL,5.0)
Return  select(4,&rfds(3),NULL,NULL,3.430000)
ASYNC NOTIFY of 'tbl2' from backend pid '9764' received
Calling select(4,&rfds(3),NULL,NULL,5.0)
Return  select(4,&rfds(3),NULL,NULL,4.120000)
ASYNC NOTIFY of 'tbl2' from backend pid '9764' received
Calling select(4,&rfds(3),NULL,NULL,5.0)
Return  select(4,&rfds(3),NULL,NULL,3.100000)
ASYNC NOTIFY of 'tbl2' from backend pid '9764' received
Calling select(4,&rfds(3),NULL,NULL,5.0)  <- let time run out
Return  select(4,&rfds(3),NULL,NULL,0.0)
Calling select(4,&rfds(3),NULL,NULL,5.0)  <- send many notify, but none were heard until later
Return  select(4,&rfds(3),NULL,NULL,0.0)
ASYNC NOTIFY of 'tbl2' from backend pid '9764' received
ASYNC NOTIFY of 'tbl2' from backend pid '9764' received
ASYNC NOTIFY of 'tbl2' from backend pid '9764' received
ASYNC NOTIFY of 'tbl2' from backend pid '9764' received
Calling ...
----
See after the select runs out the first time, it never interupts early
again.

any throughts?
james

+++++++++++++++ testlibpq.c +++++++++++++
// gcc -o testlibpq testlibpq.c -lpq -I/usr/include/postgresql
// DBHOST=db DB=test ./testlibpq

#include <stdio.h>
#include "libpq-fe.h"

#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

main()
{
    char *pghost, *pgport, *pgoptions, *pgtty;
    char *dbName;
    int nFields;
    int i, j;

    PGconn *conn;
    PGresult *res;
    PGnotify *notify;

    fd_set rfds;
    struct timeval tv;
    int pqfd;

    pghost = getenv("DBHOST");    /* host name of the backend server */
    pgport = NULL;        /* port of the backend server */
    pgoptions = NULL;        /* special options to start up the backend
                 * server */
    pgtty = NULL;        /* debugging tty for the backend server */
    dbName = getenv("DB");    /* change this to the name of your test
                   * database */

    conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
    if (PQstatus(conn) == CONNECTION_BAD) {
    fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
    fprintf(stderr, "%s", PQerrorMessage(conn));
        PQfinish(conn);
        exit(1);
    }
    pqfd = PQsocket(conn);    /* Set file handle to PQ socket */
    FD_ZERO(&rfds);
    FD_SET(pqfd, &rfds);    /* then add it to the fd set    */

    res = PQexec(conn, "LISTEN TBL2");
    if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) {
    fprintf(stderr, "LISTEN command failed\n");
    PQclear(res);
        PQfinish(conn);
        exit(1);
    }
    PQclear(res);

    while (1) {
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    fprintf(stderr, "Calling select(%d,&rfds(%d),NULL,NULL,%d.%d)\n",
        pqfd + 1, pqfd, tv.tv_sec, tv.tv_usec);
    select(pqfd + 1, &rfds, NULL, NULL, &tv);
    fprintf(stderr, "Return  select(%d,&rfds(%d),NULL,NULL,%d.%d)\n",
        pqfd + 1, pqfd, tv.tv_sec, tv.tv_usec);

    PQconsumeInput(conn);
    while ((notify = PQnotifies(conn)) != NULL) {
        fprintf(stderr,
            "ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
            notify->relname, notify->be_pid);
        free(notify);
    }
    }
    PQfinish(conn);
    return 0;
}

pgsql-general by date:

Previous
From: Devrim GUNDUZ
Date:
Subject: Re: Creating a user
Next
From: Tom Lane
Date:
Subject: Re: select + PQnotifies