Signed-off-by: Leonid Bobrov <mazoc...@disroot.org>
---
 configure.ac      |  4 ++++
 src/wayland-shm.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/configure.ac b/configure.ac
index 40cbd08..f49ca24 100644
--- a/configure.ac
+++ b/configure.ac
@@ -104,6 +104,10 @@ AC_SUBST(RT_LIBS)
 # Defines __FreeBSD__ if we're on FreeBSD, same for other *BSD
 AC_CHECK_HEADERS([sys/param.h])
 
+# mremap() and sys/mman.h are needed for the shm
+AC_CHECK_FUNCS([mremap])
+AC_CHECK_HEADERS([sys/mman.h])
+
 # waitid() and signal.h are needed for the test suite.
 AC_CHECK_FUNCS([waitid])
 AC_CHECK_HEADERS([signal.h])
diff --git a/src/wayland-shm.c b/src/wayland-shm.c
index 6f2b1d8..567dedf 100644
--- a/src/wayland-shm.c
+++ b/src/wayland-shm.c
@@ -42,6 +42,9 @@
 #include <assert.h>
 #include <signal.h>
 #include <pthread.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
 
 #include "wayland-util.h"
 #include "wayland-private.h"
@@ -87,7 +90,24 @@ shm_pool_finish_resize(struct wl_shm_pool *pool)
        if (pool->size == pool->new_size)
                return;
 
+#ifdef HAVE_MREMAP
        data = mremap(pool->data, pool->size, pool->new_size, MREMAP_MAYMOVE);
+#else
+       int32_t osize = (pool->size + PAGE_SIZE - 1) & ~PAGE_MASK;
+       if (pool->new_size <= osize) {
+               pool->size = pool->new_size;
+               return;
+       }
+       data = mmap(pool->data + osize, pool->new_size - osize, PROT_READ,
+                   MAP_SHARED | MAP_TRYFIXED, pool->fd, osize);
+       if (data == MAP_FAILED) {
+               munmap(pool->data, pool->size);
+               data = mmap(NULL, pool->new_size, PROT_READ, MAP_SHARED, 
pool->fd, 0);
+       } else {
+               pool->size = pool->new_size;
+               return;
+       }
+#endif
        if (data == MAP_FAILED) {
                wl_resource_post_error(pool->resource,
                                       WL_SHM_ERROR_INVALID_FD,
@@ -505,6 +525,7 @@ sigbus_handler(int signum, siginfo_t *info, void *context)
        sigbus_data->fallback_mapping_used = 1;
 
        /* This should replace the previous mapping */
+#ifdef HAVE_MREMAP
        if (mmap(pool->data, pool->size,
                 PROT_READ | PROT_WRITE,
                 MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS,
@@ -512,6 +533,15 @@ sigbus_handler(int signum, siginfo_t *info, void *context)
                reraise_sigbus();
                return;
        }
+#else
+       if (mmap(pool->data, pool->size,
+                PROT_READ,
+                MAP_PRIVATE | MAP_FIXED | MAP_ANON,
+                0, 0) == MAP_FAILED) {
+               reraise_sigbus();
+               return;
+       }
+#endif
 }
 
 static void
-- 
2.20.1

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to