Bug 1401776 - Raise fd limit to 4096 on Unix. r?glandium draft
authorJed Davis <jld@mozilla.com>
Thu, 10 May 2018 17:36:32 -0600
changeset 793974 0ef5678a8cb7de5ec0c5a885d25a84a30acfd6e3
parent 793895 aabfe960ab59fea2e85896b1f8050786e16ab23b
push id109548
push userbmo:jld@mozilla.com
push dateFri, 11 May 2018 04:47:47 +0000
reviewersglandium
bugs1401776, 1036682, 1161166
milestone62.0a1
Bug 1401776 - Raise fd limit to 4096 on Unix. r?glandium This is to accommodate non-networking fd usage (IPC transports, various databases, .xpi files, etc.), so it's separate from Necko's existing manipulation of the fd limit, which is tied into Necko's internal limits on how many sockets it will try to poll at once. Note that resource limits are inherited by child processes, so this needs to be done only in the parent. This patch also removes similar code used on Solaris and Mac OS X. The Mac case (bug 1036682) refers to fd use by graphics textures, which shouldn't be consuming fds anymore (even transiently) as of bug 1161166. MozReview-Commit-ID: 2uodrkW5sUn
gfx/thebes/gfxPlatformMac.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsSigHandlers.cpp
--- a/gfx/thebes/gfxPlatformMac.cpp
+++ b/gfx/thebes/gfxPlatformMac.cpp
@@ -76,28 +76,16 @@ DisableFontActivation()
 
 gfxPlatformMac::gfxPlatformMac()
 {
     DisableFontActivation();
     mFontAntiAliasingThreshold = ReadAntiAliasingThreshold();
 
     InitBackendPrefs(GetBackendPrefs());
 
-    // XXX: Bug 1036682 - we run out of fds on Mac when using tiled layers because
-    // with 256x256 tiles we can easily hit the soft limit of 800 when using double
-    // buffered tiles in e10s, so let's bump the soft limit to the hard limit for the OS
-    // up to a new cap of OPEN_MAX.
-    struct rlimit limits;
-    if (getrlimit(RLIMIT_NOFILE, &limits) == 0) {
-        limits.rlim_cur = std::min(rlim_t(OPEN_MAX), limits.rlim_max);
-        if (setrlimit(RLIMIT_NOFILE, &limits) != 0) {
-            NS_WARNING("Unable to bump RLIMIT_NOFILE to the maximum number on this OS");
-        }
-    }
-
     MacIOSurfaceLib::LoadLibrary();
 }
 
 gfxPlatformMac::~gfxPlatformMac()
 {
     gfxCoreTextShaper::Shutdown();
 }
 
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -148,19 +148,22 @@
 #include "mozilla/Omnijar.h"
 #include "mozilla/StartupTimeline.h"
 #include "mozilla/LateWriteChecks.h"
 
 #include <stdlib.h>
 #include <locale.h>
 
 #ifdef XP_UNIX
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <unistd.h>
-#include <pwd.h>
 #endif
 
 #ifdef XP_WIN
 #include <process.h>
 #include <shlobj.h>
 #include "mozilla/WinDllServices.h"
 #include "nsThreadUtils.h"
 #include <comdef.h>
@@ -3079,16 +3082,45 @@ CheckForUserMismatch()
 #else // !XP_UNIX || ANDROID
 static bool
 CheckForUserMismatch()
 {
   return false;
 }
 #endif
 
+static void
+IncreaseDescriptorLimits()
+{
+#ifdef XP_UNIX
+  // Increase the fd limit to accomodate IPC resources like shared memory.
+  static const rlim_t kFDs = 4096;
+  struct rlimit rlim;
+
+  if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
+    Output(false, "getrlimit: %s\n", strerror(errno));
+    return;
+  }
+  // Don't decrease the limit if it's already high enough, but don't
+  // try to go over the hard limit.  (RLIM_INFINITY isn't required to
+  // be the numerically largest rlim_t, so don't assume that.)
+  if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur < kFDs &&
+      rlim.rlim_cur < rlim.rlim_max) {
+    if (rlim.rlim_max != RLIM_INFINITY && rlim.rlim_max < kFDs) {
+      rlim.rlim_cur = rlim.rlim_max;
+    } else {
+      rlim.rlim_cur = kFDs;
+    }
+    if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
+      Output(false, "setrlimit: %s\n", strerror(errno));
+    }
+  }
+#endif
+}
+
 /*
  * XRE_mainInit - Initial setup and command line parameter processing.
  * Main() will exit early if either return value != 0 or if aExitFlag is
  * true.
  */
 int
 XREMain::XRE_mainInit(bool* aExitFlag)
 {
@@ -3149,16 +3181,18 @@ XREMain::XRE_mainInit(bool* aExitFlag)
   nsresult rv;
   ArgResult ar;
 
 #ifdef DEBUG
   if (PR_GetEnv("XRE_MAIN_BREAK"))
     NS_BREAK();
 #endif
 
+  IncreaseDescriptorLimits();
+
 #ifdef USE_GLX_TEST
   // bug 639842 - it's very important to fire this process BEFORE we set up
   // error handling. indeed, this process is expected to be crashy, and we
   // don't want the user to see its crashes. That's the whole reason for
   // doing this in a separate process.
   //
   // This call will cause a fork and the fork will terminate itself separately
   // from the usual shutdown sequence
--- a/toolkit/xre/nsSigHandlers.cpp
+++ b/toolkit/xre/nsSigHandlers.cpp
@@ -282,40 +282,16 @@ void InstallSignalHandlers(const char *a
     m *= (1024*1024);
     struct rlimit r;
     r.rlim_cur = m;
     r.rlim_max = m;
     setrlimit(RLIMIT_AS, &r);
   }
 #endif
 
-#if defined(SOLARIS)
-#define NOFILES 512
-
-    // Boost Solaris file descriptors
-    {
-	struct rlimit rl;
-
-	if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
-
-	    if (rl.rlim_cur < NOFILES) {
-		rl.rlim_cur = NOFILES;
-
-		if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
-		    perror("setrlimit(RLIMIT_NOFILE)");
-		    fprintf(stderr, "Cannot exceed hard limit for open files");
-		}
-#if defined(DEBUG)
-	    	if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
-		    printf("File descriptors set to %d\n", rl.rlim_cur);
-#endif //DEBUG
-	    }
-    }
-#endif //SOLARIS
-
 #if defined(MOZ_WIDGET_GTK) && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
   const char *assertString = PR_GetEnv("XPCOM_DEBUG_BREAK");
   if (assertString &&
       (!strcmp(assertString, "suspend") ||
        !strcmp(assertString, "stack") ||
        !strcmp(assertString, "abort") ||
        !strcmp(assertString, "trap") ||
        !strcmp(assertString, "break"))) {