]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix count_usable_fds() to stop trying to open files once it reaches
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 7 Aug 2005 18:47:38 +0000 (18:47 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 7 Aug 2005 18:47:38 +0000 (18:47 +0000)
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.

src/backend/storage/file/fd.c

index 1db54650eef8e9840520e668d10afa7f1e7763c2..a7540c1fc448b806055ef322b06530a24a6b34a1 100644 (file)
@@ -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);