iterator: Preserve the master lock when creating recursive iterator filters with the same lock

This way we make sure that a) the lock is always taken when checking
the cookie and calling the iterator's next functions and b) it is
not taken while calling any of the iterator filter functions.

https://bugzilla.gnome.org/show_bug.cgi?id=711138
This commit is contained in:
Stewart Brodie 2014-01-18 14:43:20 +01:00 committed by Sebastian Dröge
parent 75fe1004a5
commit f77d79f2f8

View file

@ -459,6 +459,7 @@ typedef struct _GstIteratorFilter
GstIterator iterator; GstIterator iterator;
GstIterator *slave; GstIterator *slave;
GMutex *master_lock;
GCompareFunc func; GCompareFunc func;
GValue user_data; GValue user_data;
gboolean have_user_data; gboolean have_user_data;
@ -475,15 +476,15 @@ filter_next (GstIteratorFilter * it, GValue * elem)
result = gst_iterator_next (it->slave, &item); result = gst_iterator_next (it->slave, &item);
switch (result) { switch (result) {
case GST_ITERATOR_OK: case GST_ITERATOR_OK:
if (G_LIKELY (GST_ITERATOR (it)->lock)) if (G_LIKELY (it->master_lock))
g_mutex_unlock (GST_ITERATOR (it)->lock); g_mutex_unlock (it->master_lock);
if (it->func (&item, &it->user_data) == 0) { if (it->func (&item, &it->user_data) == 0) {
g_value_copy (&item, elem); g_value_copy (&item, elem);
done = TRUE; done = TRUE;
} }
g_value_reset (&item); g_value_reset (&item);
if (G_LIKELY (GST_ITERATOR (it)->lock)) if (G_LIKELY (it->master_lock))
g_mutex_lock (GST_ITERATOR (it)->lock); g_mutex_lock (it->master_lock);
break; break;
case GST_ITERATOR_RESYNC: case GST_ITERATOR_RESYNC:
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
@ -559,6 +560,7 @@ gst_iterator_filter (GstIterator * it, GCompareFunc func,
(GstIteratorResyncFunction) filter_resync, (GstIteratorResyncFunction) filter_resync,
(GstIteratorFreeFunction) filter_free); (GstIteratorFreeFunction) filter_free);
result->master_lock = it->lock;
it->lock = NULL; it->lock = NULL;
result->func = func; result->func = func;
if (user_data) { if (user_data) {