aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-08-07 18:48:00 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-08-07 18:48:00 +0000
commitc98a606f4d16307697ef723bde5d0c6aed7f7a19 (patch)
tree5ce1da4b6a83d184e5d7f2c5876f9fd0f3b1083f
parentc76de7d85ecf7fc4034d42fc544d37f9d4aec7b6 (diff)
downloadpostgresql-c98a606f4d16307697ef723bde5d0c6aed7f7a19.tar.gz
postgresql-c98a606f4d16307697ef723bde5d0c6aed7f7a19.zip
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.
-rw-r--r--src/backend/storage/file/fd.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index d9a9c07087d..d37be532576 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
- * $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.102.2.2 2004/02/23 23:03:43 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.102.2.3 2005/08/07 18:48:00 tgl Exp $
*
* NOTES:
*
@@ -262,10 +262,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;
@@ -276,7 +282,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;
@@ -299,6 +305,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 */
@@ -333,7 +342,8 @@ set_max_safe_fds(void)
* fd.c. This ensures that 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);