[RFC PATCH] Allow more file descriptors than clients limit

Olivier Fourdan ofourdan at redhat.com
Mon Jun 22 06:52:54 PDT 2015


The X server assumes that one file descriptor is opened per client, so
it limits the number of file descriptors to the number of clients.

Unfortunately Xwayland opens a lot more file descriptors than a regular
X server because of those "weston-shared-XXXXXX" anonymous files for
sharing buffers. The number of additional file descriptors opened depends
on the clients so the actual limit depends on what applications are
running.

Once the X server (Xwayland) reaches the maximum number of file
descriptors opened, it will raise a "Maximum number of clients reached"
error and deny new connections even if the actual number of clients is
a lot less that the expected limit, thus limiting  the number of clients
in Xwayland to a much lower value than the expected default limit of 256
clients.

Raise the limit of file descriptors to match XFD_SETSIZE set in Xproto
while retaining the current limit of clients to a lower value, allowing
for more usable clients in Xwayland (even if the client limit will
remain a theoretical limit unlikely to be reachable in Xwayland).

Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
---
See also: http://lists.x.org/archives/xorg-devel/2015-May/046543.html

 include/opaque.h |  1 +
 os/WaitFor.c     |  4 ++--
 os/connection.c  | 38 ++++++++++++++++++--------------------
 3 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/include/opaque.h b/include/opaque.h
index a2c54aa..99e310e 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -36,6 +36,7 @@ from The Open Group.
 extern _X_EXPORT const char *defaultTextFont;
 extern _X_EXPORT const char *defaultCursorFont;
 extern _X_EXPORT int MaxClients;
+extern _X_EXPORT int limitFileDesc;
 extern _X_EXPORT volatile char isItTimeToYield;
 extern _X_EXPORT volatile char dispatchException;
 
diff --git a/os/WaitFor.c b/os/WaitFor.c
index 431f1a6..74e0b2e 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -220,10 +220,10 @@ WaitForSomething(int *pClientsReady)
             i = -1;
         else if (AnyClientsWriteBlocked) {
             XFD_COPYSET(&ClientsWriteBlocked, &clientsWritable);
-            i = Select(MaxClients, &LastSelectMask, &clientsWritable, NULL, wt);
+            i = Select(limitFileDesc, &LastSelectMask, &clientsWritable, NULL, wt);
         }
         else {
-            i = Select(MaxClients, &LastSelectMask, NULL, NULL, wt);
+            i = Select(limitFileDesc, &LastSelectMask, NULL, NULL, wt);
         }
         selecterr = GetErrno();
         WakeupHandler(i, (void *) &LastSelectMask);
diff --git a/os/connection.c b/os/connection.c
index c36b125..4df6a67 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -119,7 +119,7 @@ SOFTWARE.
 
 #include "probes.h"
 
-static int lastfdesc;           /* maximum file descriptor */
+int limitFileDesc = -1;           /* maximum file descriptor */
 
 fd_set WellKnownConnections;    /* Listener mask */
 fd_set EnabledDevices;          /* mask for input devices that are on */
@@ -264,44 +264,42 @@ lookup_trans_conn(int fd)
     return NULL;
 }
 
-/* Set MaxClients and lastfdesc, and allocate ConnectionTranslation */
+/* Set MaxClients and limitFileDesc, and allocate ConnectionTranslation */
 
 void
 InitConnectionLimits(void)
 {
-    lastfdesc = -1;
-
 #ifndef __CYGWIN__
 
 #if !defined(XNO_SYSCONF) && defined(_SC_OPEN_MAX)
-    lastfdesc = sysconf(_SC_OPEN_MAX) - 1;
+    limitFileDesc = sysconf(_SC_OPEN_MAX) - 1;
 #endif
 
 #ifdef HAVE_GETDTABLESIZE
-    if (lastfdesc < 0)
-        lastfdesc = getdtablesize() - 1;
+    if (limitFileDesc < 0)
+        limitFileDesc = getdtablesize() - 1;
 #endif
 
 #ifdef _NFILE
-    if (lastfdesc < 0)
-        lastfdesc = _NFILE - 1;
+    if (limitFileDesc < 0)
+        limitFileDesc = _NFILE - 1;
 #endif
 
 #endif                          /* __CYGWIN__ */
 
     /* This is the fallback */
-    if (lastfdesc < 0)
-        lastfdesc = MAXSOCKS;
+    if (limitFileDesc < 0)
+        limitFileDesc = MAXSOCKS;
 
-    if (lastfdesc > MAXSELECT)
-        lastfdesc = MAXSELECT;
+    if (limitFileDesc > MAXSELECT)
+        limitFileDesc = MAXSELECT;
 
-    if (lastfdesc > MAXCLIENTS) {
-        lastfdesc = MAXCLIENTS;
+    if (limitFileDesc > XFD_SETSIZE) {
+        limitFileDesc = XFD_SETSIZE;
         if (debug_conns)
-            ErrorF("REACHED MAXIMUM CLIENTS LIMIT %d\n", MAXCLIENTS);
+            ErrorF("REACHED MAXIMUM CONNECTIONS LIMIT %d\n", XFD_SETSIZE);
     }
-    MaxClients = lastfdesc;
+    MaxClients = MIN(MAXCLIENTS, limitFileDesc);
 
 #ifdef DEBUG
     ErrorF("InitConnectionLimits: MaxClients = %d\n", MaxClients);
@@ -309,7 +307,7 @@ InitConnectionLimits(void)
 
 #if !defined(WIN32)
     if (!ConnectionTranslation)
-        ConnectionTranslation = xnfallocarray(lastfdesc + 1, sizeof(int));
+        ConnectionTranslation = xnfallocarray(limitFileDesc + 1, sizeof(int));
 #else
     InitConnectionTranslation();
 #endif
@@ -754,7 +752,7 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time)
 
     if (
 #ifndef WIN32
-           fd >= lastfdesc
+           fd >= limitFileDesc
 #else
            XFD_SETCOUNT(&AllClients) >= MaxClients
 #endif
@@ -859,7 +857,7 @@ EstablishNewConnections(ClientPtr clientUnused, void *closure)
 
         newconn = _XSERVTransGetConnectionNumber(new_trans_conn);
 
-        if (newconn < lastfdesc) {
+        if (newconn < limitFileDesc) {
             int clientid;
 
 #if !defined(WIN32)
-- 
2.4.3



More information about the xorg-devel mailing list