Make get_flex_version.py script executable
[platform/upstream/gstreamer.git] / gst / gstiterator.c
index 56675b4..e7e5875 100644 (file)
  *
  * You should have received a copy of the GNU Library General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 
 /**
  * SECTION:gstiterator
+ * @title: GstIterator
  * @short_description: Object to retrieve multiple elements in a threadsafe
  * way.
  * @see_also: #GstElement, #GstBin
  * Various GStreamer objects provide access to their internal structures using
  * an iterator.
  *
- * In general, whenever calling a GstIterator function results in your code
- * receiving a refcounted object, the refcount for that object will have been
- * increased.  Your code is responsible for unrefing that object after use.
+ * Note that if calling a GstIterator function results in your code receiving
+ * a refcounted object (with, say, g_value_get_object()), the refcount for that
+ * object will not be increased. Your code is responsible for taking a reference
+ * if it wants to continue using it later.
  *
  * The basic use pattern of an iterator is as follows:
- *
- * <example>
- * <title>Using an iterator</title>
- *   <programlisting>
- *    it = _get_iterator(object);
- *    done = FALSE;
- *    while (!done) {
- *      switch (gst_iterator_next (it, &amp;item)) {
- *        case GST_ITERATOR_OK:
- *          ... use/change item here...
- *          g_value_reset (&amp;item);
- *          break;
- *        case GST_ITERATOR_RESYNC:
- *          ...rollback changes to items...
- *          gst_iterator_resync (it);
- *          break;
- *        case GST_ITERATOR_ERROR:
- *          ...wrong parameters were given...
- *          done = TRUE;
- *          break;
- *        case GST_ITERATOR_DONE:
- *          done = TRUE;
- *          break;
- *      }
- *    }
- *    g_value_unset (&amp;item);
- *    gst_iterator_free (it);
- *   </programlisting>
- * </example>
- *
- * Last reviewed on 2009-06-16 (0.10.24)
+ * |[<!-- language="C" -->
+ *   GstIterator *it = _get_iterator(object);
+ *   GValue item = G_VALUE_INIT;
+ *   done = FALSE;
+ *   while (!done) {
+ *     switch (gst_iterator_next (it, &amp;item)) {
+ *       case GST_ITERATOR_OK:
+ *         ...get/use/change item here...
+ *         g_value_reset (&amp;item);
+ *         break;
+ *       case GST_ITERATOR_RESYNC:
+ *         ...rollback changes to items...
+ *         gst_iterator_resync (it);
+ *         break;
+ *       case GST_ITERATOR_ERROR:
+ *         ...wrong parameters were given...
+ *         done = TRUE;
+ *         break;
+ *       case GST_ITERATOR_DONE:
+ *         done = TRUE;
+ *         break;
+ *     }
+ *   }
+ *   g_value_unset (&amp;item);
+ *   gst_iterator_free (it);
+ * ]|
  */
 
 #include "gst_private.h"
 #include <gst/gstiterator.h>
 
+/**
+ * gst_iterator_copy:
+ * @it: a #GstIterator
+ *
+ * Copy the iterator and its state.
+ *
+ * Returns: a new copy of @it.
+ */
 GstIterator *
 gst_iterator_copy (const GstIterator * it)
 {
@@ -85,16 +90,8 @@ gst_iterator_copy (const GstIterator * it)
   return copy;
 }
 
-GType
-gst_iterator_get_type (void)
-{
-  static GType type = 0;
-
-  if (G_UNLIKELY (type == 0))
-    type = g_boxed_type_register_static ("GstIterator",
-        (GBoxedCopyFunc) gst_iterator_copy, (GBoxedFreeFunc) gst_iterator_free);
-  return type;
-}
+G_DEFINE_BOXED_TYPE (GstIterator, gst_iterator,
+    (GBoxedCopyFunc) gst_iterator_copy, (GBoxedFreeFunc) gst_iterator_free);
 
 static void
 gst_iterator_init (GstIterator * it,
@@ -121,7 +118,7 @@ gst_iterator_init (GstIterator * it,
 }
 
 /**
- * gst_iterator_new:
+ * gst_iterator_new: (skip)
  * @size: the size of the iterator structure
  * @type: #GType of children
  * @lock: pointer to a #GMutex.
@@ -219,7 +216,7 @@ gst_list_iterator_free (GstListIterator * it)
 }
 
 /**
- * gst_iterator_new_list:
+ * gst_iterator_new_list: (skip)
  * @type: #GType of elements
  * @lock: pointer to a #GMutex protecting the list.
  * @master_cookie: pointer to a guint32 that is incremented when the list
@@ -231,7 +228,7 @@ gst_list_iterator_free (GstListIterator * it)
  * Create a new iterator designed for iterating @list.
  *
  * The list you iterate is usually part of a data structure @owner and is
- * protected with @lock. 
+ * protected with @lock.
  *
  * The iterator will use @lock to retrieve the next item of the list and it
  * will then call the @item function before releasing @lock again.
@@ -300,7 +297,7 @@ gst_iterator_pop (GstIterator * it)
  * @it: The #GstIterator to iterate
  * @elem: (out caller-allocates): pointer to hold next element
  *
- * Get the next item from the iterator in @elem. 
+ * Get the next item from the iterator in @elem.
  *
  * Only when this function returns %GST_ITERATOR_OK, @elem will contain a valid
  * value. @elem must have been initialized to the type of the iterator or
@@ -313,7 +310,7 @@ gst_iterator_pop (GstIterator * it)
  *
  * A return value of %GST_ITERATOR_RESYNC indicates that the element list was
  * concurrently updated. The user of @it should call gst_iterator_resync() to
- * get the newly updated list. 
+ * get the newly updated list.
  *
  * A return value of %GST_ITERATOR_ERROR indicates an unrecoverable fatal error.
  *
@@ -459,6 +456,7 @@ typedef struct _GstIteratorFilter
   GstIterator iterator;
   GstIterator *slave;
 
+  GMutex *master_lock;
   GCompareFunc func;
   GValue user_data;
   gboolean have_user_data;
@@ -475,15 +473,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:
@@ -502,6 +500,8 @@ static void
 filter_copy (const GstIteratorFilter * it, GstIteratorFilter * copy)
 {
   copy->slave = gst_iterator_copy (it->slave);
+  copy->master_lock = copy->slave->lock ? copy->slave->lock : it->master_lock;
+  copy->slave->lock = NULL;
 
   if (it->have_user_data) {
     memset (&copy->user_data, 0, sizeof (copy->user_data));
@@ -559,6 +559,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) {
@@ -588,8 +589,8 @@ gst_iterator_filter (GstIterator * it, GCompareFunc func,
  * This procedure can be used (and is used internally) to implement the
  * gst_iterator_foreach() and gst_iterator_find_custom() operations.
  *
- * The fold will proceed as long as @func returns TRUE. When the iterator has no
- * more arguments, %GST_ITERATOR_DONE will be returned. If @func returns FALSE,
+ * The fold will proceed as long as @func returns %TRUE. When the iterator has no
+ * more arguments, %GST_ITERATOR_DONE will be returned. If @func returns %FALSE,
  * the fold will stop, and %GST_ITERATOR_OK will be returned. Errors or resyncs
  * will cause fold to return %GST_ITERATOR_ERROR or %GST_ITERATOR_RESYNC as
  * appropriate.
@@ -607,6 +608,8 @@ gst_iterator_fold (GstIterator * it, GstIteratorFoldFunction func,
   GValue item = { 0, };
   GstIteratorResult result;
 
+  g_return_val_if_fail (it != NULL, GST_ITERATOR_ERROR);
+
   while (1) {
     result = gst_iterator_next (it, &item);
     switch (result) {
@@ -625,7 +628,13 @@ gst_iterator_fold (GstIterator * it, GstIteratorFoldFunction func,
   }
 
 fold_done:
+
+#if GLIB_CHECK_VERSION (2, 48, 0)
   g_value_unset (&item);
+#else
+  if (item.g_type != 0)
+    g_value_unset (&item);
+#endif
 
   return result;
 }
@@ -705,10 +714,10 @@ find_custom_fold_func (const GValue * item, GValue * ret,
  *
  * The iterator will not be freed.
  *
- * This function will return FALSE if an error happened to the iterator
+ * This function will return %FALSE if an error happened to the iterator
  * or if the element wasn't found.
  *
- * Returns: Returns TRUE if the element was found, else FALSE.
+ * Returns: Returns %TRUE if the element was found, else %FALSE.
  *
  * MT safe.
  */
@@ -800,8 +809,6 @@ gst_single_object_iterator_free (GstSingleObjectIterator * it)
  * for the #GstPadIterIntLinkFunction.
  *
  * Returns: the new #GstIterator for @object.
- *
- * Since: 0.10.25
  */
 GstIterator *
 gst_iterator_new_single (GType type, const GValue * object)