GstShmAllocator: Use shm_open() instead of temporary file

There is no guarantee that g_get_user_runtime_dir() is in a tmpfs. Using
an explicit shared memory API seems safer for all POSIX platforms.

Note that Android does not have shm_open() and only added memfd_create()
since API level 30 (Android 11).

Sponsored-by: Netflix Inc.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5328>
This commit is contained in:
Xavier Claessens 2023-09-18 14:38:24 -04:00 committed by GStreamer Marge Bot
parent d59ea1caf0
commit c0ce677dfc
2 changed files with 12 additions and 10 deletions

View file

@ -52,7 +52,7 @@ static GstMemory *
gst_shm_allocator_alloc (GstAllocator * allocator, gsize size, gst_shm_allocator_alloc (GstAllocator * allocator, gsize size,
GstAllocationParams * params) GstAllocationParams * params)
{ {
#ifdef HAVE_MMAP #if defined(HAVE_MEMFD_CREATE) || defined(HAVE_SHM_OPEN)
GstShmAllocator *self = GST_SHM_ALLOCATOR (allocator); GstShmAllocator *self = GST_SHM_ALLOCATOR (allocator);
int fd; int fd;
GstMemory *mem; GstMemory *mem;
@ -75,19 +75,17 @@ gst_shm_allocator_alloc (GstAllocator * allocator, gsize size,
{ {
char filename[1024]; char filename[1024];
static int init = 0; static int init = 0;
int flags = O_RDWR | O_CREAT | O_EXCL;
int perms = S_IRUSR | S_IWUSR | S_IRGRP;
/* allocate shm pool */ snprintf (filename, 1024, "/gst-shm.%d.%d", getpid (), init++);
snprintf (filename, 1024, "%s/%s-%d-%s", g_get_user_runtime_dir (), fd = shm_open (filename, flags, perms);
"gst-shm", init++, "XXXXXX");
fd = g_mkstemp (filename);
if (fd < 0) { if (fd < 0) {
GST_ERROR_OBJECT (self, "opening temp file %s failed: %s", filename, GST_ERROR_OBJECT (self, "shm_open() failed: %s", strerror (errno));
strerror (errno));
return NULL; return NULL;
} }
unlink (filename); shm_unlink (filename);
} }
if (ftruncate (fd, size) < 0) { if (ftruncate (fd, size) < 0) {
@ -104,7 +102,7 @@ gst_shm_allocator_alloc (GstAllocator * allocator, gsize size,
return NULL; return NULL;
} }
/* we need to map the memory in order to unlink the file without losing it */ /* Map R/W and keep it mapped to avoid useless mmap/munmap */
if (!gst_memory_map (mem, &info, GST_MAP_READWRITE)) { if (!gst_memory_map (mem, &info, GST_MAP_READWRITE)) {
GST_ERROR_OBJECT (self, "GstFdMemory map failed"); GST_ERROR_OBJECT (self, "GstFdMemory map failed");
close (fd); close (fd);

View file

@ -28,6 +28,10 @@ if cc.has_function('memfd_create')
'-DHAVE_MEMFD_CREATE', '-DHAVE_MEMFD_CREATE',
'-D_GNU_SOURCE', '-D_GNU_SOURCE',
] ]
elif cc.has_function('shm_open')
gst_allocators_cargs += [
'-DHAVE_SHM_OPEN',
]
endif endif
gstallocators = library('gstallocators-@0@'.format(api_version), gstallocators = library('gstallocators-@0@'.format(api_version),