summaryrefslogtreecommitdiff
path: root/os
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-11-21 22:12:34 -0800
committerKeith Packard <keithp@keithp.com>2013-12-02 12:57:08 -0800
commitb6d7ed4d787a652e8150532f384bfdf51760f3c2 (patch)
tree8d7bf4b1a92ecccefe2a0aa2832108967a700627 /os
parentcc63204926c6da83d9221c5f8c0dc8f5e2f2481d (diff)
miext: Move SyncShm FDs out of the way of clients
Applications may end up allocating a bunch of shmfence objects, each of which uses a file descriptor, which must be kept open lest some other client ask for a copy of it later on. Lacking an API that can turn a memory mapping back into a file descriptor, about the best we can do is push the file descriptors out of the way of other X clients so that we don't run out of the ability to accept new connections. This uses fcntl F_GETFD to push the FD up above MAXCLIENTS. Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Julien Cristau <jcristau@debian.org>
Diffstat (limited to 'os')
-rw-r--r--os/utils.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/os/utils.c b/os/utils.c
index fb20da755..608ee6ab0 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -2071,3 +2071,27 @@ FormatUInt64Hex(uint64_t num, char *string)
string[len] = '\0';
}
+
+/* Move a file descriptor out of the way of our select mask; this
+ * is useful for file descriptors which will never appear in the
+ * select mask to avoid reducing the number of clients that can
+ * connect to the server
+ */
+int
+os_move_fd(int fd)
+{
+ int newfd;
+
+#ifdef F_DUPFD_CLOEXEC
+ newfd = fcntl(fd, F_DUPFD_CLOEXEC, MAXCLIENTS);
+#else
+ newfd = fcntl(fd, F_DUPFD, MAXCLIENTS);
+#endif
+ if (newfd < 0)
+ return fd;
+#ifndef F_DUPFD_CLOEXEC
+ fcntl(newfd, F_SETFD, FD_CLOEXEC);
+#endif
+ close(fd);
+ return newfd;
+}