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