fdmemory: Allow for change of protection mode
authorTobias Ronge <tobiasr@lnxhplap16.se.axis.com>
Tue, 27 Oct 2020 13:12:42 +0000 (14:12 +0100)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 28 Oct 2020 17:11:05 +0000 (17:11 +0000)
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>

gst-libs/gst/allocators/gstfdmemory.c
tests/check/libs/allocators.c

index 9efcf89..398914c 100644 (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)) {
index c96edf1..36c4a38 100644 (file)
 #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;
 }