From 1e6063f6fc9fa02bd2f12ad9e60cbc2529fc0377 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
Date: Sat, 1 Jul 2017 19:08:46 -0700
Subject: [PATCH] QWaylandShmBuffer: use a memfd if we can for a simple memory
 buffer

which has a file descriptor we can also use to share with

Change-Id: I8d96dea9955d4c749b99fffd14cd61628c616b30
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
---
 src/client/qwaylandshmbackingstore.cpp | 35 ++++++++++++++++++++------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp
index 4c7c53b2..2085bc59 100644
--- a/src/client/qwaylandshmbackingstore.cpp
+++ b/src/client/qwaylandshmbackingstore.cpp
@@ -55,6 +55,13 @@
 
 #include <unistd.h>
 #include <sys/mman.h>
+
+#ifdef Q_OS_LINUX
+#  include <sys/syscall.h>
+// from linux/memfd.h:
+#  define MFD_CLOEXEC       0x0001U
+#endif
+
 QT_BEGIN_NAMESPACE
 
 namespace QtWaylandClient {
@@ -71,15 +78,29 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
 {
     int stride = size.width() * 4;
     int alloc = stride * size.height();
-    int fd;
-
-    QTemporaryFile tmp(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) +
-                       QLatin1String("/wayland-shm-XXXXXX"));
-    if (!tmp.open() || !tmp.resize(alloc)) {
-        qWarning("QWaylandShmBuffer: failed: %s", qUtf8Printable(tmp.errorString()));
+    int fd = -1;
+
+#ifdef SYS_memfd_create
+    fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC);
+#endif
+
+    QScopedPointer<QFile> filePointer;
+
+    if (fd == -1) {
+        auto tmpFile = new QTemporaryFile (QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) +
+                                       QLatin1String("/wayland-shm-XXXXXX"));
+        tmpFile->open();
+        filePointer.reset(tmpFile);
+    } else {
+        auto file = new QFile;
+        file->open(fd, QIODevice::ReadWrite | QIODevice::Unbuffered, QFile::AutoCloseHandle);
+        filePointer.reset(file);
+    }
+    if (!filePointer->isOpen() || !filePointer->resize(alloc)) {
+        qWarning("QWaylandShmBuffer: failed: %s", qUtf8Printable(filePointer->errorString()));
         return;
     }
-    fd = tmp.handle();
+    fd = filePointer->handle();
 
     // map ourselves: QFile::map() will unmap when the object is destroyed,
     // but we want this mapping to persist (unmapping in destructor)
-- 
GitLab