fdmemory: Allow for change of protection mode

After a memory has been unmapped, protection mode can now be changed
when mapping it again.

See https://bugzilla.gnome.org/show_bug.cgi?id=789952.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/895>
This commit is contained in:
Tobias Ronge 2020-10-27 14:12:42 +01:00 committed by GStreamer Merge Bot
parent eb216e3865
commit e2a1aa44df
2 changed files with 49 additions and 1 deletions

View file

@ -97,6 +97,12 @@ gst_fd_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
if ((mem->mmapping_flags & prot) == prot) {
ret = mem->data;
mem->mmap_count++;
} else if ((mem->flags & GST_FD_MEMORY_FLAG_KEEP_MAPPED)
&& mem->mmap_count == 0
&& mprotect (mem->data, gmem->maxsize, prot) == 0) {
ret = mem->data;
mem->mmapping_flags = prot;
mem->mmap_count++;
}
goto out;
@ -154,8 +160,12 @@ gst_fd_mem_unmap (GstMemory * gmem)
if (gmem->parent)
return gst_fd_mem_unmap (gmem->parent);
if (mem->flags & GST_FD_MEMORY_FLAG_KEEP_MAPPED)
if (mem->flags & GST_FD_MEMORY_FLAG_KEEP_MAPPED) {
g_mutex_lock (&mem->lock);
mem->mmap_count--;
g_mutex_unlock (&mem->lock);
return;
}
g_mutex_lock (&mem->lock);
if (mem->data && !(--mem->mmap_count)) {

View file

@ -25,8 +25,13 @@
#include <glib/gstdio.h>
#include <gst/check/gstcheck.h>
#include <fcntl.h>
#include <gst/allocators/gstdmabuf.h>
#include <gst/allocators/gstfdmemory.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define FILE_SIZE 4096
@ -60,6 +65,38 @@ GST_START_TEST (test_dmabuf)
GST_END_TEST;
GST_START_TEST (test_fdmem)
{
GstAllocator *alloc;
GstMemory *mem;
GstMapInfo info;
int fd;
const char *data = "0123456789";
fd = open ("test.txt", O_RDWR | O_CREAT);
g_assert (write (fd, data, 10) == 10);
alloc = gst_fd_allocator_new ();
g_assert (alloc);
mem = gst_fd_allocator_alloc (alloc, fd, 10, GST_FD_MEMORY_FLAG_KEEP_MAPPED);
g_assert (gst_memory_map (mem, &info, GST_MAP_READ));
g_assert (info.data[5] == '5');
gst_memory_unmap (mem, &info);
g_assert (gst_memory_map (mem, &info, GST_MAP_WRITE));
info.data[5] = 'X';
gst_memory_unmap (mem, &info);
g_assert (gst_memory_map (mem, &info, GST_MAP_READ));
g_assert (info.data[5] == 'X');
gst_memory_unmap (mem, &info);
gst_memory_unref (mem);
g_assert (remove ("test.txt") == 0);
gst_object_unref (alloc);
}
GST_END_TEST;
static Suite *
allocators_suite (void)
{
@ -68,6 +105,7 @@ allocators_suite (void)
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_dmabuf);
tcase_add_test (tc_chain, test_fdmem);
return s;
}