diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index bf5b8b7d3ef..6ea89cabc97 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -6710,15 +6710,22 @@ clear_socket_set(socket_set *sa) static void add_socket_to_set(socket_set *sa, int fd, int idx) { - if (fd < 0 || fd >= FD_SETSIZE) + /* See connect_slot() for background on this code. */ +#ifdef WIN32 + if (sa->fds.fd_count + 1 >= FD_SETSIZE) { - /* - * Doing a hard exit here is a bit grotty, but it doesn't seem worth - * complicating the API to make it less grotty. - */ - pg_log_fatal("too many client connections for select()"); + pg_log_fatal("too many concurrent database clients for this platform: %d", + sa->fds.fd_count + 1); exit(1); } +#else + if (fd < 0 || fd >= FD_SETSIZE) + { + pg_log_fatal("socket file descriptor out of range for select(): %d", + fd); + exit(1); + } +#endif FD_SET(fd, &sa->fds); if (fd > sa->maxfd) sa->maxfd = fd; diff --git a/src/bin/scripts/scripts_parallel.c b/src/bin/scripts/scripts_parallel.c index ec264a269a7..426897a87ab 100644 --- a/src/bin/scripts/scripts_parallel.c +++ b/src/bin/scripts/scripts_parallel.c @@ -223,15 +223,39 @@ ParallelSlotsSetup(const ConnParams *cparams, conn = connectDatabase(cparams, progname, echo, false, true); /* - * Fail and exit immediately if trying to use a socket in an - * unsupported range. POSIX requires open(2) to use the lowest - * unused file descriptor and the hint given relies on that. + * POSIX defines FD_SETSIZE as the highest file descriptor + * acceptable to FD_SET() and allied macros. Windows defines it + * as a ceiling on the count of file descriptors in the set, not a + * ceiling on the value of each file descriptor; see + * https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-select + * and + * https://learn.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-fd_set. + * We can't ignore that, because Windows starts file descriptors + * at a higher value, delays reuse, and skips values. With less + * than ten concurrent file descriptors, opened and closed + * rapidly, one can reach file descriptor 1024. + * + * Doing a hard exit here is a bit grotty, but it doesn't seem + * worth complicating the API to make it less grotty. */ - if (PQsocket(conn) >= FD_SETSIZE) +#ifdef WIN32 + if (i >= FD_SETSIZE) { - pg_log_fatal("too many jobs for this platform -- try %d", i); + pg_log_fatal("too many jobs for this platform: %d", i); exit(1); } +#else + { + int fd = PQsocket(conn); + + if (fd >= FD_SETSIZE) + { + pg_log_fatal("socket file descriptor out of range for select(): %d", + fd); + exit(1); + } + } +#endif init_slot(slots + i, conn); }