diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index c5e028bd88d..d14937711f3 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -6377,15 +6377,24 @@ 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. - */ - fprintf(stderr, "too many client connections for select()\n"); + fprintf(stderr, + "too many concurrent database clients for this platform: %d\n", + sa->fds.fd_count + 1); exit(1); } +#else + if (fd < 0 || fd >= FD_SETSIZE) + { + fprintf(stderr, + "socket file descriptor out of range for select(): %d\n", + fd); + exit(1); + } +#endif FD_SET(fd, &sa->fds); if (fd > sa->maxfd) sa->maxfd = fd; diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index bff6802dd36..97ec3ad0e99 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -635,15 +635,39 @@ vacuum_one_database(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); }