*
* 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, &item)) {
- * case GST_ITERATOR_OK:
- * ... use/change item here...
- * g_value_reset (&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 (&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, &item)) {
+ * case GST_ITERATOR_OK:
+ * ...get/use/change item here...
+ * g_value_reset (&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 (&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)
{
* 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.
* @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
*
* 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.
*
GstIterator iterator;
GstIterator *slave;
+ GMutex *master_lock;
GCompareFunc func;
GValue user_data;
gboolean have_user_data;
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:
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 (©->user_data, 0, sizeof (copy->user_data));
(GstIteratorResyncFunction) filter_resync,
(GstIteratorFreeFunction) filter_free);
+ result->master_lock = it->lock;
it->lock = NULL;
result->func = func;
if (user_data) {
* 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.
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) {
}
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;
}
*
* 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.
*/
* for the #GstPadIterIntLinkFunction.
*
* Returns: the new #GstIterator for @object.
- *
- * Since: 0.10.25
*/
GstIterator *
gst_iterator_new_single (GType type, const GValue * object)