Re: BUG #19424: Concurrent PQconnectdb() calls hang on Windows - Mailing list pgsql-bugs

From Danimar Ribeiro
Subject Re: BUG #19424: Concurrent PQconnectdb() calls hang on Windows
Date
Msg-id 660f580d-d47c-418b-8caf-6228c1e1b4e9@gmail.com
Whole thread
In response to BUG #19424: Concurrent PQconnectdb() calls hang on Windows  (PG Bug reporting form <noreply@postgresql.org>)
List pgsql-bugs
On Tue, Mar 3, 2026 at 4:23 PM, David Ritter wrote:
> The following bug has been logged on the website:
> 
> Bug reference:      19424
> Logged by:          David Ritter
> Email address:      david.ritter@gmail.com
> PostgreSQL version: 18.3
> Operating system:   Windows 11
> Description:
> 
> Versions affected: libpq 17.4, 18.3 (likely all 17.x+)
> 
> Platform: Windows (MSVC 19.x, x86_64). Not reproducible on Linux (RHEL 9,
> tested 1000 runs with 100 threads each).
> 
> Description: When multiple threads each call PQconnectdb() concurrently with
> independent connection strings, most or all threads hang indefinitely.
> PQisthreadsafe() returns 1. A single serial warmup connection succeeds. The
> attached reproducer spawns N threads and reports how many complete within 30
> seconds.
> 
> 

Hi David,

I was looking into this report and tried to reproduce the issue on 
Windows 11 with MSVC, testing against both the latest master and 
REL_17_STABLE.

It turns out this isn't a bug in libpq, but rather a limitation in the 
Windows API used within the test reproducer script itself.

The `WaitForMultipleObjects` function in Windows has a hardcoded limit 
of `MAXIMUM_WAIT_OBJECTS` (which is 64). Because the script passes 100 
threads to it at once, the function fails and returns instantly. 
Consequently, the script's timer immediately ends while the threads are 
still spinning up, reading their `done` flags as 0. The script 
misinterprets this instant API failure as a 30-second timeout/hang.

I modified the test script to wait in chunks of 60 threads to bypass the 
Windows limit:

     for (i = 0; i < num_threads; i += 60) {
         int chunk_size = (num_threads - i > 60) ? 60 : (num_threads - i);
         WaitForMultipleObjects(chunk_size, &threads[i], TRUE, 
TIMEOUT_SECONDS * 1000);
     }

After applying this fix to the test script, I ran it with 300 concurrent 
threads. The issue disappears completely, and the result is `300 OK` 
with zero hung threads. libpq handles the concurrency safely on Windows.

Are you still experiencing this issue in your actual application? If so, 
could you provide an updated script to replicate the issue? I would be 
happy to test it again.

Regards
Danimar



pgsql-bugs by date:

Previous
From: Paul Kim
Date:
Subject: Re: [PATCH v1] psql: schema-qualify catalog references in a tab-completion query
Next
From: Peter Geoghegan
Date:
Subject: Re: BUG #17949: Adding an index introduces serialisation anomalies.