X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstiterator.c;h=e7e5875ddc009c153c1b742fee419800105838ad;hb=dac5966da6a0f53d0443dfa1ac239289028c415d;hp=99369dff920b7bb33b5ff0938eeeebdf56ac13d4;hpb=1fbcc71dbdff79d70b0abe1285f694f3d4596564;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstiterator.c b/gst/gstiterator.c index 99369df..e7e5875 100644 --- a/gst/gstiterator.c +++ b/gst/gstiterator.c @@ -16,12 +16,13 @@ * * 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 @@ -32,47 +33,51 @@ * 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: - * - * - * Using an iterator - * - * 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); - * - * - * - * Last reviewed on 2009-06-16 (0.10.24) + * |[ + * 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_iterator_copy: + * @it: a #GstIterator + * + * Copy the iterator and its state. + * + * Returns: a new copy of @it. + */ GstIterator * gst_iterator_copy (const GstIterator * it) { @@ -223,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. @@ -292,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 @@ -305,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. * @@ -451,6 +456,7 @@ typedef struct _GstIteratorFilter GstIterator iterator; GstIterator *slave; + GMutex *master_lock; GCompareFunc func; GValue user_data; gboolean have_user_data; @@ -467,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: @@ -494,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 (©->user_data, 0, sizeof (copy->user_data)); @@ -551,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) { @@ -580,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. @@ -599,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) { @@ -617,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; } @@ -697,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. */ @@ -792,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)