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 <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
