[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