From: Tom Lane Date: Sun, 7 Aug 2005 18:47:38 +0000 (+0000) Subject: Fix count_usable_fds() to stop trying to open files once it reaches X-Git-Tag: REL8_0_4~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4cf0feae2ca4d722cd33cfbdd35651625c81748e;p=thirdparty%2Fpostgresql.git Fix count_usable_fds() to stop trying to open files once it reaches max_files_per_process. Going further than that is just a waste of cycles, and it seems that current Cygwin does not cope gracefully with deliberately running the system out of FDs. Per Andrew Dunstan. --- diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 1db54650eef..a7540c1fc44 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.115 2004/12/31 22:00:51 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.115.4.1 2005/08/07 18:47:38 tgl Exp $ * * NOTES: * @@ -267,10 +267,16 @@ pg_fdatasync(int fd) * count_usable_fds --- count how many FDs the system will let us open, * and estimate how many are already open. * + * We stop counting if usable_fds reaches max_to_probe. Note: a small + * value of max_to_probe might result in an underestimate of already_open; + * we must fill in any "gaps" in the set of used FDs before the calculation + * of already_open will give the right answer. In practice, max_to_probe + * of a couple of dozen should be enough to ensure good results. + * * We assume stdin (FD 0) is available for dup'ing */ static void -count_usable_fds(int *usable_fds, int *already_open) +count_usable_fds(int max_to_probe, int *usable_fds, int *already_open) { int *fd; int size; @@ -281,7 +287,7 @@ count_usable_fds(int *usable_fds, int *already_open) size = 1024; fd = (int *) palloc(size * sizeof(int)); - /* dup until failure ... */ + /* dup until failure or probe limit reached */ for (;;) { int thisfd; @@ -304,6 +310,9 @@ count_usable_fds(int *usable_fds, int *already_open) if (highestfd < thisfd) highestfd = thisfd; + + if (used >= max_to_probe) + break; } /* release the files we opened */ @@ -338,7 +347,8 @@ set_max_safe_fds(void) * we won't exceed either max_files_per_process or the * experimentally-determined EMFILE limit. */ - count_usable_fds(&usable_fds, &already_open); + count_usable_fds(max_files_per_process, + &usable_fds, &already_open); max_safe_fds = Min(usable_fds, max_files_per_process - already_open);