[PATCH v1] Fix races in Windows pthread emulation

From: Harrison Booth <harrisontbooth(at)gmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: [PATCH v1] Fix races in Windows pthread emulation
Date: 2026-07-23 18:18:25
Message-ID: CAAH-eSXFXSEtXpb4kUAGOKKdm3o3y-yWfjsJ7R7zUL6g-swuzw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On native Windows ARM64, the ECPG thread/alloc test could hang until
Meson's 1000-second timeout. The cause was a race in the Windows pthread
mutex emulation.

The mutex initialization path used InterlockedExchange to set initstate to
2. A waiting thread could therefore change the fully initialized state from
1 back to 2. pthread_mutex_unlock would then see a state other than 1,
return EINVAL, and leave the critical section locked.

This patch uses InterlockedCompareExchange to claim initialization only
when initstate is 0. It also uses interlocked reads and publication for the
mutex state. The duplicated mutex implementations in ECPG and libpq receive
the same fix.

pthread_once previously used a Boolean state with plain reads and writes.
MSVC uses /volatile:iso on ARM64, so those accesses do not provide the
acquire and release ordering needed to publish initialized state. The patch
changes pthread_once_t to LONG and uses interlocked operations for every
read and publication.

I tested this against master at
1c9c35890421e96a91129b51f2c6446a6d95af95 on Windows 11 Pro ARM64 with
MSVC 19.44.35228. Both the native ARM64 build and the x64 build running
under ARM64 emulation compiled successfully. On each architecture:

- ecpg/ecpg passed 67 subtests.
- libpq/001_uri, 002_api, 003_load_balance_host_list, and 006_service
passed 241 subtests.

I did not add a new test because the existing ECPG thread/alloc test
exercises the failing path and reproduced the hang on native ARM64.

The mutex fast path now performs an interlocked read before entering or
leaving the critical section, and pthread_once checks do the same. I have
not benchmarked that cost. The patch changes no non-Windows code or
user-facing interface, so it requires no documentation change.

CommitFest entry 6314 has a pending patch that moves the libpq Windows
pthread implementation into src/port without changing this state machine.
This patch applies to current master. If that refactor lands first, the
libpq hunk will need a straightforward rebase.

This patch is intended for review and application to master.

Best,
Harrison

Attachment Content-Type Size
v1-0001-Fix-races-in-Windows-pthread-emulation.patch application/octet-stream 4.4 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Masahiko Sawada 2026-07-23 18:22:01 Re: Fix race condition in pg_get_publication_tables with concurrent DROP TABLE
Previous Message Tom Lane 2026-07-23 18:07:07 Re: POC: PLpgSQL FOREACH IN JSON ARRAY