[gtk+/gtk-3-14] broadway: Handle shm_open failing by falling back on tmp files
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-3-14] broadway: Handle shm_open failing by falling back on tmp files
- Date: Tue, 7 Jul 2015 17:46:20 +0000 (UTC)
commit 64770685a911fcc65fe436cd99206152f67f60e6
Author: Alexander Larsson <alexl redhat com>
Date: Thu Jun 25 21:15:46 2015 +0200
broadway: Handle shm_open failing by falling back on tmp files
This is required if /dev/shm is not mounted on your system, which can
happen for instance in certain container configurations.
gdk/broadway/broadway-server.c | 18 ++++++++++++--
gdk/broadway/gdkbroadway-server.c | 45 +++++++++++++++++++++++++++++-------
2 files changed, 51 insertions(+), 12 deletions(-)
---
diff --git a/gdk/broadway/broadway-server.c b/gdk/broadway/broadway-server.c
index 9f06c08..ee53359 100644
--- a/gdk/broadway/broadway-server.c
+++ b/gdk/broadway/broadway-server.c
@@ -819,19 +819,31 @@ map_named_shm (char *name, gsize size)
int fd;
void *ptr;
+ char *filename = NULL;
fd = shm_open(name, O_RDONLY, 0600);
if (fd == -1)
{
- perror ("Failed to shm_open");
- return NULL;
+ filename = g_build_filename (g_get_tmp_dir (), name, NULL);
+ fd = open (filename, O_RDONLY);
+ if (fd == -1)
+ {
+ perror ("Failed to map shm");
+ return NULL;
+ }
}
ptr = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
(void) close(fd);
- shm_unlink (name);
+ if (filename)
+ {
+ unlink (filename);
+ g_free (filename);
+ }
+ else
+ shm_unlink (name);
return ptr;
diff --git a/gdk/broadway/gdkbroadway-server.c b/gdk/broadway/gdkbroadway-server.c
index ecd24ae..c566591 100644
--- a/gdk/broadway/gdkbroadway-server.c
+++ b/gdk/broadway/gdkbroadway-server.c
@@ -524,10 +524,11 @@ _gdk_broadway_server_window_set_transient_for (GdkBroadwayServer *server,
}
static void *
-map_named_shm (char *name, gsize size)
+map_named_shm (char *name, gsize size, gboolean *is_shm)
{
#ifdef G_OS_UNIX
+ char *filename = NULL;
int fd;
void *ptr;
int res;
@@ -535,10 +536,24 @@ map_named_shm (char *name, gsize size)
fd = shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
if (fd == -1)
{
- if (errno != EEXIST)
- g_error ("Unable to allocate shared mem for window");
- return NULL;
+ if (errno == EEXIST)
+ return NULL;
+
+ filename = g_build_filename (g_get_tmp_dir (), name, NULL);
+
+ fd = open (filename, O_RDWR | O_CREAT | O_EXCL, 0600);
+ g_free (filename);
+ if (fd == -1)
+ {
+ if (errno != EEXIST)
+ g_error ("Unable to allocate shared mem for window");
+ return NULL;
+ }
+ else
+ *is_shm = FALSE;
}
+ else
+ *is_shm = TRUE;
res = ftruncate (fd, size);
g_assert (res != -1);
@@ -547,7 +562,10 @@ map_named_shm (char *name, gsize size)
res = posix_fallocate (fd, 0, size);
if (res != 0 && errno == ENOSPC)
{
- shm_unlink (name);
+ if (filename)
+ unlink (filename);
+ else
+ shm_unlink (name);
g_error ("Not enough shared memory for window surface");
}
#endif
@@ -579,6 +597,7 @@ map_named_shm (char *name, gsize size)
return NULL;
}
+ *is_shm = TRUE;
res = ftruncate (fd, size);
g_assert (res != -1);
@@ -614,7 +633,7 @@ make_valid_fs_char (char c)
/* name must have at least space for 34 bytes */
static gpointer
-create_random_shm (char *name, gsize size)
+create_random_shm (char *name, gsize size, gboolean *is_shm)
{
guint32 r;
int i, o;
@@ -638,7 +657,7 @@ create_random_shm (char *name, gsize size)
}
name[o++] = 0;
- ptr = map_named_shm (name, size);
+ ptr = map_named_shm (name, size, is_shm);
if (ptr)
return ptr;
}
@@ -650,6 +669,7 @@ typedef struct {
char name[36];
void *data;
gsize data_size;
+ gboolean is_shm;
} BroadwayShmSurfaceData;
static void
@@ -660,7 +680,14 @@ shm_data_destroy (void *_data)
#ifdef G_OS_UNIX
munmap (data->data, data->data_size);
- shm_unlink (data->name);
+ if (data->is_shm)
+ shm_unlink (data->name);
+ else
+ {
+ char *filename = g_build_filename (g_get_tmp_dir (), data->name, NULL);
+ unlink (filename);
+ g_free (filename);
+ }
#elif defined(G_OS_WIN32)
@@ -689,7 +716,7 @@ _gdk_broadway_server_create_surface (int width,
data = g_new (BroadwayShmSurfaceData, 1);
data->data_size = width * height * sizeof (guint32);
- data->data = create_random_shm (data->name, data->data_size);
+ data->data = create_random_shm (data->name, data->data_size, &data->is_shm);
surface = cairo_image_surface_create_for_data ((guchar *)data->data,
CAIRO_FORMAT_ARGB32, width, height, width * sizeof
(guint32));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]