#define _GNU_SOURCE
+#include "config.h"
+
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>
#include <errno.h>
+#include <fcntl.h>
#include "wayland-util.h"
#include "wayland-private.h"
char *data;
int32_t size;
int32_t new_size;
+ bool sigbus_is_impossible;
};
struct wl_shm_buffer {
uint32_t id, int fd, int32_t size)
{
struct wl_shm_pool *pool;
+ int seals;
if (size <= 0) {
wl_resource_post_error(resource,
goto err_close;
}
+#ifdef HAVE_MEMFD_CREATE
+ seals = fcntl(fd, F_GET_SEALS);
+ if (seals == -1)
+ seals = 0;
+ pool->sigbus_is_impossible = (seals & F_SEAL_SHRINK) ? true : false;
+#else
+ pool->sigbus_is_impossible = false;
+#endif
+
pool->internal_refcount = 1;
pool->external_refcount = 0;
pool->size = size;
struct wl_shm_pool *pool = buffer->pool;
struct wl_shm_sigbus_data *sigbus_data;
+ if (pool->sigbus_is_impossible)
+ return;
+
pthread_once(&wl_shm_sigbus_once, init_sigbus_data_key);
sigbus_data = pthread_getspecific(wl_shm_sigbus_data_key);
WL_EXPORT void
wl_shm_buffer_end_access(struct wl_shm_buffer *buffer)
{
- struct wl_shm_sigbus_data *sigbus_data =
- pthread_getspecific(wl_shm_sigbus_data_key);
+ struct wl_shm_pool *pool = buffer->pool;
+ struct wl_shm_sigbus_data *sigbus_data;
+ if (pool->sigbus_is_impossible)
+ return;
+
+ sigbus_data = pthread_getspecific(wl_shm_sigbus_data_key);
assert(sigbus_data && sigbus_data->access_count >= 1);
if (--sigbus_data->access_count == 0) {