[PATCH] Add PQgetThreadLock() to expose the Kerberos/Curl mutex
Hello all,
libpq has some third-party dependencies (currently, Kerberos and Curl)
that aren't threadsafe in some situations. We protect the affected
code with a locking callback, and we allow applications to override
that callback globally because they might also be using those
third-party dependencies. The history of the API is at [1, 2].
That appears to work well enough for clients that control the main()
function. With OAuth, there are use cases where third-party code
living "behind" libpq (i.e. in libraries invoked via callbacks) may
need to make use of the threadlock as well. So this patch just adds a
getter API. libpq-oauth would be the first client of the new function
for PG19.
This doesn't actually expose any net-new internals:
PQregisterThreadLock() already returned the previous function pointer
to the caller, but that can't be used by a library that just wants to
*use* the existing lock without modifying it.
Best I can tell, the setter has always been unsafe for concurrent use
(it's madness to change the locking callback while a connection might
be using it, right?), so I've noted this explicitly in the
documentation.
Any objections?
Thanks!
--Jacob
[1]: /messages/by-id/3FB943E4.90508@colorfullife.com
[2]: /messages/by-id/4001594F.6060304@colorfullife.com
Attachments:
0001-libpq-Add-PQgetThreadLock-to-mirror-PQregisterThread.patchapplication/octet-stream; name=0001-libpq-Add-PQgetThreadLock-to-mirror-PQregisterThread.patchDownload+21-4
On Feb 28, 2026, at 04:38, Jacob Champion <jacob.champion@enterprisedb.com> wrote:
Hello all,
libpq has some third-party dependencies (currently, Kerberos and Curl)
that aren't threadsafe in some situations. We protect the affected
code with a locking callback, and we allow applications to override
that callback globally because they might also be using those
third-party dependencies. The history of the API is at [1, 2].That appears to work well enough for clients that control the main()
function. With OAuth, there are use cases where third-party code
living "behind" libpq (i.e. in libraries invoked via callbacks) may
need to make use of the threadlock as well. So this patch just adds a
getter API. libpq-oauth would be the first client of the new function
for PG19.This doesn't actually expose any net-new internals:
PQregisterThreadLock() already returned the previous function pointer
to the caller, but that can't be used by a library that just wants to
*use* the existing lock without modifying it.Best I can tell, the setter has always been unsafe for concurrent use
(it's madness to change the locking callback while a connection might
be using it, right?), so I've noted this explicitly in the
documentation.Any objections?
Thanks!
--Jacob[1] /messages/by-id/3FB943E4.90508@colorfullife.com
[2] /messages/by-id/4001594F.6060304@colorfullife.com
<0001-libpq-Add-PQgetThreadLock-to-mirror-PQregisterThread.patch>
I wonder instead of exposing the lock itself, would it be cleaner to add a pair of Lock/Unlock APIs?
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
On Fri, Feb 27, 2026 at 12:38:34PM -0800, Jacob Champion wrote:
libpq has some third-party dependencies (currently, Kerberos and Curl)
that aren't threadsafe in some situations. We protect the affected
code with a locking callback, and we allow applications to override
that callback globally because they might also be using those
third-party dependencies. The history of the API is at [1, 2].
Well, that's ancient stuff. krb4? 4?!
Anyways, I'm quite curious about any thread safety problems you are
aware of in Kerberos implementations today. As for curl, it wants to be
initialized much like OpenSSL used to want to be initialized (thankfully
no more), and that's a problem.
Nico
--
On Fri, Feb 27, 2026 at 7:13 PM Chao Li <li.evan.chao@gmail.com> wrote:
I wonder instead of exposing the lock itself, would it be cleaner to add a pair of Lock/Unlock APIs?
The lock is *already* exposed. For better or worse, this is the API
we've chosen. And since the need for the lock will hopefully decrease
over time, I don't think we should put effort into improving it.
On Fri, Feb 27, 2026 at 8:40 PM Nico Williams <nico@cryptonector.com> wrote:
Well, that's ancient stuff. krb4? 4?!
Anyways, I'm quite curious about any thread safety problems you are
aware of in Kerberos implementations today.
Ha, I'd wondered how much of the documentation (and locking) around
this was relevant in 2026. Not something I plan to tackle in the near
future, though :D
As for curl, it wants to be
initialized much like OpenSSL used to want to be initialized (thankfully
no more), and that's a problem.
Curl is also in the "thankfully no more" bucket, but we support older
Red Hat installations that don't have the improvement yet.
Thanks,
--Jacob
On Fri, Feb 27, 2026 at 12:38 PM Jacob Champion
<jacob.champion@enterprisedb.com> wrote:
Any objections?
Hearing none so far, I'll try to get this pushed sometime today, or
tomorrow at the latest.
Thanks,
--Jacob