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
This commit is contained in:
Matthew Waters 2015-05-31 21:25:23 +10:00
parent 935ecd85ea
commit ad4569c893
2 changed files with 44 additions and 4 deletions

View file

@ -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;

View file

@ -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;
}