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 19ac93c..65cc543 100644 --- a/configure.ac +++ b/configure.ac @@ -95,6 +95,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