| From: | Heikki Linnakangas <hlinnaka(at)iki(dot)fi> |
|---|---|
| To: | Jelte Fennema-Nio <postgres(at)jeltef(dot)nl>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Alvaro Herrera <alvherre(at)alvh(dot)no-ip(dot)org>, Jacob Champion <jacob(dot)champion(at)enterprisedb(dot)com> |
| Subject: | Re: Don't use the deprecated and insecure PQcancel in our frontend tools anymore |
| Date: | 2026-03-05 18:30:29 |
| Message-ID: | 88dfe280-ba29-4943-95b8-63abc9f3f771@iki.fi |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On 08/02/2026 21:05, Jelte Fennema-Nio wrote:
> On Sun Dec 14, 2025 at 3:40 PM CET, Jelte Fennema-Nio wrote:
>> A bunch of frontend tools, including psql, still used PQcancel to send
>> cancel requests to the server. That function is insecure, because it
>> does not use encryption to send the cancel request. This starts using
>> the new cancellation APIs (introduced in 61461a300) for all these
>> frontend tools.
>
> Small update. Split up the fe_utils and pg_dump changes into separate
> commits, to make patches easier to review. Also use non-blocking writes
> to the self-pipe from the signal handler to avoid potential deadlocks
> (extremely unlikely for such blocks to occur, but better safe than sorry).
Had a brief look at this:
It took me a while to get the big picture of how this works. cancel.c
could use some high-level comments explaining how to use the facility;
it's a real mixed bag right now.
The SIGINT handler now does three things:
- Set CancelRequested global variable,
- call callback if set, and
- wake up the cancel thread to send the cancel message, if cancel
connection is set.
There's no high-level overview documentation or comments on how those
three mechanism work or interact. It took me a while to understand that
they are really separate, alternative ways to handle SIGINT, all mashed
into the same signal handler function. At first read, I thought they're
somehow part of the one same mechanism.
The cancelConn mechanism is a global variable, which means that it can
only be used with one connection in the process. That's OK with the
current callers, but seems short-sighted. What if we wanted to use it
for pgbench, for example, which uses multiple threads and connections?
Or if we changed pg_dump to use multiple threads, like you also
suggested as a possible follow-up.
The "self-pipe trick" usually refers to interrupting the main thread
from select(); this uses it to wake up the other, separate cancellation
thread. That's fine, but again it took me a while to understand that
that's what it does. Comments!
This is racy, if the cancellation thread doesn't immediately process the
wakeup. For example, because it's still busy processing a previous
wakeup, because there's a network hiccup or something. By the time the
cancellation thread runs, the main thread might already be running a
different query than it was when the user hit CTRL-C.
- Heikki
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Noah Misch | 2026-03-05 18:52:03 | Re: gistGetFakeLSN() can return incorrect LSNs |
| Previous Message | Andrey Borodin | 2026-03-05 18:26:30 | Re: gistGetFakeLSN() can return incorrect LSNs |