xserver: Branch 'master' - 4 commits

Keith Packard keithp at kemper.freedesktop.org
Mon Dec 2 13:09:38 PST 2013


 Xext/shm.c              |   34 +++++++++++++++++++++++++++++++---
 configure.ac            |   45 ++++++++++++++++++++++++++++++++++++++++++++-
 include/dix-config.h.in |    3 +++
 include/os.h            |    3 +++
 miext/sync/misyncshm.c  |    5 ++++-
 os/utils.c              |   24 ++++++++++++++++++++++++
 6 files changed, 109 insertions(+), 5 deletions(-)

New commits:
commit eafba23b34be31c141ddafb8380520ac9a0622ac
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Nov 21 22:45:18 2013 -0800

    miext/sync: Handle libxshmfence API change
    
    libxshmfence had an unfortunate 'int32_t' type for the mapped fence.
    That changed to exposing a 'struct shmfence' instead, which is nice
    and opaque and offers fine type checking across the API.
    
    This patch requires the newer version of the library and uses
    the new interface type.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/configure.ac b/configure.ac
index f6ecdc6..5a36e54 100644
--- a/configure.ac
+++ b/configure.ac
@@ -787,7 +787,7 @@ DMXPROTO="dmxproto >= 2.2.99.1"
 VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1"
 WINDOWSWMPROTO="windowswmproto"
 APPLEWMPROTO="applewmproto >= 1.4"
-XSHMFENCE="xshmfence"
+XSHMFENCE="xshmfence >= 1.1"
 
 dnl Required modules
 XPROTO="xproto >= 7.0.22"
diff --git a/miext/sync/misyncshm.c b/miext/sync/misyncshm.c
index 20780fd..01f82fc 100644
--- a/miext/sync/misyncshm.c
+++ b/miext/sync/misyncshm.c
@@ -38,7 +38,7 @@
 static DevPrivateKeyRec syncShmFencePrivateKey;
 
 typedef struct _SyncShmFencePrivate {
-    int32_t             *fence;
+    struct xshmfence    *fence;
     int                 fd;
 } SyncShmFencePrivateRec, *SyncShmFencePrivatePtr;
 
commit b6d7ed4d787a652e8150532f384bfdf51760f3c2
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Nov 21 22:12:34 2013 -0800

    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 at keithp.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/include/os.h b/include/os.h
index 450e1a8..9b67294 100644
--- a/include/os.h
+++ b/include/os.h
@@ -686,4 +686,7 @@ LogPrintMarkers(void);
 extern _X_EXPORT void
 xorg_backtrace(void);
 
+extern _X_EXPORT int
+os_move_fd(int fd);
+
 #endif                          /* OS_H */
diff --git a/miext/sync/misyncshm.c b/miext/sync/misyncshm.c
index 3f9350a..20780fd 100644
--- a/miext/sync/misyncshm.c
+++ b/miext/sync/misyncshm.c
@@ -32,6 +32,7 @@
 #include "pixmapstr.h"
 #include <sys/mman.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <X11/xshmfence.h>
 
 static DevPrivateKeyRec syncShmFencePrivateKey;
@@ -126,6 +127,7 @@ miSyncShmCreateFenceFromFd(ScreenPtr pScreen, SyncFence *pFence, int fd, Bool in
 
     miSyncInitFence(pScreen, pFence, initially_triggered);
 
+    fd = os_move_fd(fd);
     pPriv->fence = xshmfence_map_shm(fd);
     if (pPriv->fence) {
         pPriv->fd = fd;
@@ -145,6 +147,7 @@ miSyncShmGetFenceFd(ScreenPtr pScreen, SyncFence *pFence)
         pPriv->fd = xshmfence_alloc_shm();
         if (pPriv->fd < 0)
             return -1;
+        pPriv->fd = os_move_fd(pPriv->fd);
         pPriv->fence = xshmfence_map_shm(pPriv->fd);
         if (!pPriv->fence) {
             close (pPriv->fd);
diff --git a/os/utils.c b/os/utils.c
index fb20da7..608ee6a 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;
+}
commit cc63204926c6da83d9221c5f8c0dc8f5e2f2481d
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 13 14:16:33 2013 +0900

    Xext: Use SHMDIR and O_TMPFILE when creating mapping files
    
    ShmCreateSegment asks for a file descriptor for a memory mapped file
    created by the X server. This patch uses O_TMPFILE where available,
    and also uses the SHMDIR directory to store the files, both for the
    O_TMPFILE and mkstemp cases.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/Xext/shm.c b/Xext/shm.c
index d014b91..1957a95 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -37,6 +37,7 @@ in this Software without prior written authorization from The Open Group.
 #include <sys/shm.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <fcntl.h>
 #include <X11/X.h>
 #include <X11/Xproto.h>
 #include "misc.h"
@@ -1177,6 +1178,35 @@ ProcShmAttachFd(ClientPtr client)
 }
 
 static int
+shm_tmpfile(void)
+{
+#ifdef SHMDIR
+	int	fd;
+	int	flags;
+	char	template[] = SHMDIR "/shmfd-XXXXXX";
+#ifdef O_TMPFILE
+	fd = open(SHMDIR, O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666);
+	if (fd >= 0) {
+		ErrorF ("Using O_TMPFILE\n");
+		return fd;
+	}
+	ErrorF ("Not using O_TMPFILE\n");
+#endif
+	fd = mkstemp(template);
+	if (fd < 0)
+		return -1;
+	unlink(template);
+	if (fcntl(fd, F_GETFD, &flags) >= 0) {
+		flags |= FD_CLOEXEC;
+		(void) fcntl(fd, F_SETFD, &flags);
+	}
+	return fd;
+#else
+        return -1;
+#endif
+}
+
+static int
 ProcShmCreateSegment(ClientPtr client)
 {
     int fd;
@@ -1188,17 +1218,15 @@ ProcShmCreateSegment(ClientPtr client)
         .sequenceNumber = client->sequence,
         .length = 0,
     };
-    char template[] = "/tmp/shm-XXXXXX";
 
     REQUEST_SIZE_MATCH(xShmCreateSegmentReq);
     if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) {
         client->errorValue = stuff->readOnly;
         return BadValue;
     }
-    fd = mkstemp(template);
+    fd = shm_tmpfile();
     if (fd < 0)
         return BadAlloc;
-    unlink(template);
     if (ftruncate(fd, stuff->size) < 0) {
         close(fd);
         return BadAlloc;
commit 5a969f0928b84da5cfe0777dfb542caaacc915ad
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 13 12:17:10 2013 +0900

    Select directory for MIT-SHM temp files at configure time
    
    By default, this looks through a list of directories to find one which
    exists, but can be overridden with --with-shared-memory-dir=PATH
    
    This patch doesn't actually do anything with this directory, just
    makes it available in the configuration
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/configure.ac b/configure.ac
index 6197e9b..f6ecdc6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1086,6 +1086,49 @@ case "$DRI2,$HAVE_DRI2PROTO" in
 esac
 AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes)
 
+dnl
+dnl Locate a suitable tmp file system for creating shared memeory files
+dnl
+
+AC_ARG_WITH(shared-memory-dir, AS_HELP_STRING([--with-shared-memory-dir=PATH], [Path to directory in a world-writable temporary directory for anonymous shared memory (default: auto)]),
+[],
+[with_shared_memory_dir=yes])
+
+shmdirs="/run/shm /var/tmp /tmp"
+
+case x"$with_shared_memory_dir" in
+xyes)
+	for dir in $shmdirs; do
+		case x"$with_shared_memory_dir" in
+		xyes)
+			echo Checking temp dir "$dir"
+			if test -d "$dir"; then
+				with_shared_memory_dir="$dir"
+			fi
+			;;
+		esac
+	done
+	;;
+x/*)
+	;;
+xno)
+	;;
+*)
+	AC_MSG_ERROR([Invalid directory specified for --with-shared-memory-dir: $with_shared_memory_dir])
+	;;
+esac
+
+case x"$with_shared_memory_dir" in
+xyes)
+	AC_MSG_ERROR([No directory found for shared memory temp files.])
+	;;
+xno)
+	;;
+*)
+	AC_DEFINE_UNQUOTED(SHMDIR, ["$with_shared_memory_dir"], [Directory for shared memory temp files])
+	;;
+esac
+
 AC_ARG_ENABLE(xtrans-send-fds,	AS_HELP_STRING([--disable-xtrans-send-fds], [Use Xtrans support for fd passing (default: auto)]), [XTRANS_SEND_FDS=$enableval], [XTRANS_SEND_FDS=auto])
 
 case "x$XTRANS_SEND_FDS" in
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index d4fbe99..3066100 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -466,4 +466,7 @@
 /* Wrap SIGBUS to catch MIT-SHM faults */
 #undef BUSFAULT
 
+/* Directory for shared memory temp files */
+#undef SHMDIR
+
 #endif /* _DIX_CONFIG_H_ */


More information about the xorg-commit mailing list