iterator: Preserve the master lock when creating recursive iterator filters with...
authorStewart Brodie <stewart@eh.org>
Sat, 18 Jan 2014 13:43:20 +0000 (14:43 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Sat, 18 Jan 2014 13:48:54 +0000 (14:48 +0100)
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

gst/gstiterator.c

index f2b49936ff47e0be247567d49caf6a6b560fd171..ae579423f3572fd3a9207f9a9c80331b4db78b80 100644 (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) {