Re: BUG #18096: In edge-triggered epoll and kqueue, PQconsumeInput/PQisBusy are insufficient for correct async ops.

From: mah0x211 <mah0x211(at)gmail(dot)com>
To:
Cc: pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #18096: In edge-triggered epoll and kqueue, PQconsumeInput/PQisBusy are insufficient for correct async ops.
Date: 2023-09-19 13:16:07
Message-ID: CA+T1w-ix8R=Fufg_9DEiGkEyc61nKUSaYCoRUhvANLMjEiprOg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Thanks for the reply.
I'm not good at English, so I am using machine translation to correct it.
some sentences may be difficult to understand.

The following test code performs asynchronous operations using libpq along
with either epoll or kqueue. I wasn't sure if it's appropriate to include
a large code in an email, so I've uploaded the test code to a gist.

https://gist.github.com/mah0x211/3ea723b3ddb406319650428087e9d066

I can easily reproduce the issue on my macOS system which using kqueue, but
it takes many runs to reproduce on my Linux system using epoll.

In the case of edge-triggered mode, `consume_input()` may fail depending on
the amount of data received. This happens when `PQconsumeInput()` doesn't
read all the data received on the socket (The size of the received data of
the socket is larger than the size of the buffer area), and the subsequent
call to `PQisBusy()` returns `1`. Then, waiting for a socket read event,
it fails with a timeout.

In the case of level-triggered mode, there's no problem as events will be
continuously generated while data remains in the socket.

The main issue here is whether to wait for data to arrive in the main loop
or
to call `PQconsumeInput()` again. This decision requires checking errno on
the application side.

Is there any other way to resolve this issue?

-------------------------------

Masatoshi Fukunaga

GitHub: https://github.com/mah0x211/

2023年9月8日(金) 23:33 Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>:

> PG Bug reporting form <noreply(at)postgresql(dot)org> writes:
> > When processing asynchronous commands, I call the `PQconsumeInput` and
> > `PQisBusy` functions to check if data has arrived, as shown below, but
> this
> > does not work correctly in edge trigger mode for epoll and kqueue.
>
> You have not really provided any evidence of a bug. The contract
> for PQconsumeInput is that it will consume *some* input if any
> is available, not that it will consume *all* available input.
> (I don't think there is much reason to try to change that. In the
> first place, there might not be enough buffer space, and in the
> second place, even if it did consume all input, more might arrive
> immediately after it looks.)
>
> Without a self-contained test case, it's hard to be sure what is going
> wrong for you; but my guess is that this is a bug in the way you are
> checking for more available input rather than something libpq did
> wrong.
>
> > However, the `pqReadData()` function will not call the `pqsecure_read()`
> > function until the `errno` is set to `EAGAIN` or `EWOULDBLOCK`,
>
> Uh ... what?
>
> regards, tom lane
>

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message Thomas Schweikle 2023-09-19 13:58:23 Stackbuilder fails to download application list
Previous Message Alexander Lakhin 2023-09-19 13:00:06 Re: BUG #17928: Standby fails to decode WAL on termination of primary