From ad4569c893e10e0e2dcaab3a076d837ae2bffa35 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Sun, 31 May 2015 21:25:23 +1000 Subject: [PATCH] miniobject: disallow a double write/exclusive lock gst_memory_lock (mem, WRITE | EXCLUSIVE); gst_memory_lock (mem, WRITE | EXCLUSIVE); Succeeds when the part-miniobject.txt design doc suggests that this should fail: "A gst_mini_object_lock() can fail when a WRITE lock is requested and the exclusive counter is > 1. Indeed a GstMiniObject object with an exclusive counter 1 is locked EXCLUSIVELY by at least 2 objects and is therefore not writable." https://bugzilla.gnome.org/show_bug.cgi?id=750172 --- gst/gstminiobject.c | 10 ++++++---- tests/check/gst/gstmemory.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/gst/gstminiobject.c b/gst/gstminiobject.c index d65bd02..9486dad 100644 --- a/gst/gstminiobject.c +++ b/gst/gstminiobject.c @@ -193,11 +193,13 @@ gst_mini_object_lock (GstMiniObject * object, GstLockFlags flags) access_mode &= ~GST_LOCK_FLAG_EXCLUSIVE; } - if (access_mode) { - /* shared counter > 1 and write access is not allowed */ - if (access_mode & GST_LOCK_FLAG_WRITE && IS_SHARED (state)) - goto lock_failed; + /* shared counter > 1 and write access is not allowed */ + if (((state & GST_LOCK_FLAG_WRITE) != 0 + || (access_mode & GST_LOCK_FLAG_WRITE) != 0) + && IS_SHARED (newstate)) + goto lock_failed; + if (access_mode) { if ((state & LOCK_FLAG_MASK) == 0) { /* nothing mapped, set access_mode */ newstate |= access_mode; diff --git a/tests/check/gst/gstmemory.c b/tests/check/gst/gstmemory.c index 56b3020..d1964da 100644 --- a/tests/check/gst/gstmemory.c +++ b/tests/check/gst/gstmemory.c @@ -550,6 +550,43 @@ GST_START_TEST (test_alloc_params) GST_END_TEST; +GST_START_TEST (test_lock) +{ + GstMemory *mem; + + mem = gst_allocator_alloc (NULL, 10, NULL); + fail_unless (mem != NULL); + + /* test exclusivity */ + fail_unless (gst_memory_lock (mem, GST_MAP_WRITE | GST_LOCK_FLAG_EXCLUSIVE)); + fail_if (gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE)); + fail_unless (gst_memory_lock (mem, GST_MAP_WRITE)); + gst_memory_unlock (mem, GST_MAP_WRITE | GST_LOCK_FLAG_EXCLUSIVE); + gst_memory_unlock (mem, GST_MAP_WRITE); + + /* no lock here */ + + fail_unless (gst_memory_lock (mem, GST_MAP_READ | GST_LOCK_FLAG_EXCLUSIVE)); + fail_unless (gst_memory_lock (mem, GST_MAP_READ | GST_LOCK_FLAG_EXCLUSIVE)); + gst_memory_unlock (mem, GST_MAP_READ | GST_LOCK_FLAG_EXCLUSIVE); + gst_memory_unlock (mem, GST_MAP_READ | GST_LOCK_FLAG_EXCLUSIVE); + + /* no lock here */ + + fail_unless (gst_memory_lock (mem, + GST_MAP_READWRITE | GST_LOCK_FLAG_EXCLUSIVE)); + fail_unless (gst_memory_lock (mem, GST_MAP_READ)); + fail_if (gst_memory_lock (mem, GST_MAP_READ | GST_LOCK_FLAG_EXCLUSIVE)); + fail_if (gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE)); + fail_unless (gst_memory_lock (mem, GST_MAP_WRITE)); + gst_memory_unlock (mem, GST_MAP_WRITE); + gst_memory_unlock (mem, GST_MAP_READ); + gst_memory_unlock (mem, GST_MAP_READWRITE | GST_LOCK_FLAG_EXCLUSIVE); + + gst_memory_unref (mem); +} + +GST_END_TEST; static Suite * gst_memory_suite (void) @@ -569,6 +606,7 @@ gst_memory_suite (void) tcase_add_test (tc_chain, test_map_nested); tcase_add_test (tc_chain, test_map_resize); tcase_add_test (tc_chain, test_alloc_params); + tcase_add_test (tc_chain, test_lock); return s; } -- 2.7.4