Commit 5337ad46 authored by Tom Lane's avatar Tom Lane

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.
parent 9b29f9f3
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.118 2005/07/04 04:51:48 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.119 2005/08/07 18:47:19 tgl Exp $
* *
* NOTES: * NOTES:
* *
...@@ -300,10 +300,16 @@ pg_fdatasync(int fd) ...@@ -300,10 +300,16 @@ pg_fdatasync(int fd)
* count_usable_fds --- count how many FDs the system will let us open, * count_usable_fds --- count how many FDs the system will let us open,
* and estimate how many are already 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 * We assume stdin (FD 0) is available for dup'ing
*/ */
static void 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 *fd;
int size; int size;
...@@ -314,7 +320,7 @@ count_usable_fds(int *usable_fds, int *already_open) ...@@ -314,7 +320,7 @@ count_usable_fds(int *usable_fds, int *already_open)
size = 1024; size = 1024;
fd = (int *) palloc(size * sizeof(int)); fd = (int *) palloc(size * sizeof(int));
/* dup until failure ... */ /* dup until failure or probe limit reached */
for (;;) for (;;)
{ {
int thisfd; int thisfd;
...@@ -337,6 +343,9 @@ count_usable_fds(int *usable_fds, int *already_open) ...@@ -337,6 +343,9 @@ count_usable_fds(int *usable_fds, int *already_open)
if (highestfd < thisfd) if (highestfd < thisfd)
highestfd = thisfd; highestfd = thisfd;
if (used >= max_to_probe)
break;
} }
/* release the files we opened */ /* release the files we opened */
...@@ -364,14 +373,16 @@ set_max_safe_fds(void) ...@@ -364,14 +373,16 @@ set_max_safe_fds(void)
int usable_fds; int usable_fds;
int already_open; int already_open;
/* /*----------
* We want to set max_safe_fds to MIN(usable_fds, * We want to set max_safe_fds to
* max_files_per_process - already_open) less the slop factor for * MIN(usable_fds, max_files_per_process - already_open)
* files that are opened without consulting fd.c. This ensures that * less the slop factor for files that are opened without consulting
* we won't exceed either max_files_per_process or the * fd.c. This ensures that we won't exceed either max_files_per_process
* experimentally-determined EMFILE limit. * 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); max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment