Re: libpq ASYNC with PQgetResult and PQisBusy - Mailing list pgsql-general

From Raimon Fernandez
Subject Re: libpq ASYNC with PQgetResult and PQisBusy
Date
Msg-id 2C5CFB1E-FAAA-4CFD-A7F2-1DFBCD194010@montx.com
Whole thread Raw
In response to Re: libpq ASYNC with PQgetResult and PQisBusy  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: libpq ASYNC with PQgetResult and PQisBusy  (Alban Hertroys <dalroi@solfertje.student.utwente.nl>)
List pgsql-general
On 20dic, 2010, at 18:48 , Tom Lane wrote:

>> So, now I'm using the PQisBusy to check if postgre is still busy and I can safely call the PQgetResult wihtout
blocking,or just wait *some time* before sending a new PQisBusy. 
>
> Your proposed code is still a busy-wait loop.

This is how are made all the examples I've found.

Last year I was implementing the FE/BE protocol v3 and there I was using what you proposed, a TCP/Socket with events,
noloops and no waits, just events. 

> What you should be doing is waiting for some data to arrive on the socket.

where I have to wait, in a function inside my plugin or from the framework that uses my plugin ?

> Once you see
> read-ready on the socket, call PQconsumeInput, then check PQisBusy to
> see if the query is complete or not.  If not, go back to waiting on the
> socket.  Typically you'd use select() or poll() to watch for both data
> on libpq's socket and whatever other events your app is interested in.

Here is what I've found:

extern int    PQsocket(const PGconn *conn);

There are some examples in the postgreSQL documentation:

/*
* Sleep untilsomething happens on the connection. We use select(2)
* to wait for input, but you could also use poll() or similar
* facilities.
*/


int    sock;
fd_set    input_mask;

sock = PQsocket(conn);

if (sock < 0) break; /* shouldn’t happen */

FD_ZERO(&input_mask);
FD_SET(sock, &input_mask);

if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0) {

    fprintf(stderr, "select() failed: %s\n", strerror(errno));
    exit_nicely(conn);
}

/* Now check for input */
PQconsumeInput(conn);

while ((notify = PQnotifies(conn)) != NULL) {

    fprintf(stderr, "ASYNC NOTIFY of ’%s’ received from backend pid %d\n", notify->relname, notify->be_pid);
    PQfreemem(notify);
}


The select(2) that says that are using for wait is this line ? if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0)
{

I can't see where is 'sleeping'


and the approach you are refering, is the only way to non-block the plugin calls and postgreSQL ?



>> here is my montxPG_isBusy
>
>> static long montxPG_isBusy()
>
>> {    int execStatus;
>>     int consumeeVar;
>
>>     consumeeVar = PQconsumeInput(gPGconn);
>
>>     if (consumeeVar == 0) return (long) PGRES_FATAL_ERROR;
>
>>         execStatus = PQisBusy(gPGconn);
>
>>     return (long) execStatus;
>
>> }
>
> This code seems a bit confused.  PQisBusy returns a bool (1/0), not a
> value of ExecStatusType.

yes, here the execStatus is the name of the int, and yes, I know, a bad name ...

thanks again,

regards,

r.

pgsql-general by date:

Previous
From: Scott Marlowe
Date:
Subject: Re: PostgreSQL Trusted Startup
Next
From: Kenneth Buckler
Date:
Subject: Re: PostgreSQL Trusted Startup