Обсуждение: select + PQnotifies

Поиск
Список
Период
Сортировка

select + PQnotifies

От
James Leigh
Дата:
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;
}

Re: select + PQnotifies

От
Tom Lane
Дата:
James Leigh <james.leigh@ottawa.com> writes:
> 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.

You're forgetting that the rdfs parameter to select() is a read/write
parameter.  You need to set the bit for the file you're interested in
every time through the loop, not just once.

            regards, tom lane