Make code safe for -Wredundant-decls
[platform/upstream/gstreamer.git] / gst / gstobject.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *                    2005 Wim Taymans <wim@fluendo.com>
5  *
6  * gstobject.c: Fundamental class used for all of GStreamer
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 /**
25  * SECTION:gstobject
26  * @short_description: Base class for the GStreamer object hierarchy
27  *
28  * #GstObject provides a root for the object hierarchy tree filed in by the
29  * GStreamer library.  It is currently a thin wrapper on top of
30  * #GObject. It is an abstract class that is not very usable on its own.
31  *
32  * #GstObject gives us basic refcounting, parenting functionality and locking.
33  * Most of the function are just extended for special GStreamer needs and can be
34  * found under the same name in the base class of #GstObject which is #GObject
35  * (e.g. g_object_ref() becomes gst_object_ref()).
36  *
37  * The most interesting difference between #GstObject and #GObject is the
38  * "floating" reference count. A #GObject is created with a reference count of
39  * 1, owned by the creator of the #GObject. (The owner of a reference is the
40  * code section that has the right to call gst_object_unref() in order to
41  * remove that reference.) A #GstObject is created with a reference count of 1
42  * also, but it isn't owned by anyone; Instead, the initial reference count
43  * of a #GstObject is "floating". The floating reference can be removed by
44  * anyone at any time, by calling gst_object_sink().  gst_object_sink() does
45  * nothing if an object is already sunk (has no floating reference).
46  *
47  * When you add a #GstElement to its parent container, the parent container will
48  * do this:
49  * <informalexample>
50  * <programlisting>
51  *   gst_object_ref (GST_OBJECT (child_element));
52  *   gst_object_sink (GST_OBJECT (child_element));
53  * </programlisting>
54  * </informalexample>
55  * This means that the container now owns a reference to the child element
56  * (since it called gst_object_ref()), and the child element has no floating
57  * reference.
58  *
59  * The purpose of the floating reference is to keep the child element alive
60  * until you add it to a parent container, which then manages the lifetime of
61  * the object itself:
62  * <informalexample>
63  * <programlisting>
64  *    element = gst_element_factory_make (factoryname, name);
65  *    // element has one floating reference to keep it alive
66  *    gst_bin_add (GST_BIN (bin), element);
67  *    // element has one non-floating reference owned by the container
68  * </programlisting>
69  * </informalexample>
70  *
71  * Another effect of this is, that calling gst_object_unref() on a bin object,
72  * will also destoy all the #GstElement objects in it. The same is true for
73  * calling gst_bin_remove().
74  *
75  * Special care has to be taken for all methods that gst_object_sink() an object
76  * since if the caller of those functions had a floating reference to the object,
77  * the object reference is now invalid.
78  *
79  * In contrast to #GObject instances, #GstObject adds a name property. The functions
80  * gst_object_set_name() and gst_object_get_name() are used to set/get the name
81  * of the object.
82  *
83  * Last reviewed on 2005-11-09 (0.9.4)
84  */
85
86 #include "gst_private.h"
87
88 #include "gstobject.h"
89 #include "gstmarshal.h"
90 #include "gstinfo.h"
91 #include "gstutils.h"
92
93 #ifndef GST_DISABLE_TRACE
94 #include "gsttrace.h"
95 static GstAllocTrace *_gst_object_trace;
96 #endif
97
98 #define DEBUG_REFCOUNT
99
100 /* Object signals and args */
101 /* FIXME-0.11: have a read-only parent property instead of the two signals
102  * then we get notify::parent for free */
103 enum
104 {
105   PARENT_SET,
106   PARENT_UNSET,
107 #ifndef GST_DISABLE_LOADSAVE
108   OBJECT_SAVED,
109 #endif
110   DEEP_NOTIFY,
111   LAST_SIGNAL
112 };
113
114 enum
115 {
116   ARG_0,
117   ARG_NAME
118       /* FILL ME */
119 };
120
121 enum
122 {
123   SO_OBJECT_LOADED,
124   SO_LAST_SIGNAL
125 };
126
127 /* maps type name quark => count */
128 static GData *object_name_counts = NULL;
129
130 G_LOCK_DEFINE_STATIC (object_name_mutex);
131
132 typedef struct _GstSignalObject GstSignalObject;
133 typedef struct _GstSignalObjectClass GstSignalObjectClass;
134
135 static GType gst_signal_object_get_type (void);
136
137 #ifndef GST_DISABLE_LOADSAVE
138 static guint gst_signal_object_signals[SO_LAST_SIGNAL] = { 0 };
139 #endif
140
141 static void gst_object_set_property (GObject * object, guint prop_id,
142     const GValue * value, GParamSpec * pspec);
143 static void gst_object_get_property (GObject * object, guint prop_id,
144     GValue * value, GParamSpec * pspec);
145 static void gst_object_dispatch_properties_changed (GObject * object,
146     guint n_pspecs, GParamSpec ** pspecs);
147
148 static void gst_object_dispose (GObject * object);
149 static void gst_object_finalize (GObject * object);
150
151 static gboolean gst_object_set_name_default (GstObject * object);
152
153 #ifndef GST_DISABLE_LOADSAVE
154 static void gst_object_real_restore_thyself (GstObject * object,
155     xmlNodePtr self);
156 #endif
157
158 static GObjectClass *parent_class = NULL;
159 static guint gst_object_signals[LAST_SIGNAL] = { 0 };
160
161 G_DEFINE_ABSTRACT_TYPE (GstObject, gst_object, G_TYPE_OBJECT);
162
163 static void
164 gst_object_class_init (GstObjectClass * klass)
165 {
166   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
167
168   parent_class = g_type_class_peek_parent (klass);
169
170 #ifndef GST_DISABLE_TRACE
171   _gst_object_trace = gst_alloc_trace_register (g_type_name (GST_TYPE_OBJECT));
172 #endif
173
174   gobject_class->set_property = gst_object_set_property;
175   gobject_class->get_property = gst_object_get_property;
176
177   g_object_class_install_property (gobject_class, ARG_NAME,
178       g_param_spec_string ("name", "Name", "The name of the object",
179           NULL,
180           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
181
182   /**
183    * GstObject::parent-set:
184    * @gstobject: a #GstObject
185    * @parent: the new parent
186    *
187    * Emitted when the parent of an object is set.
188    */
189   gst_object_signals[PARENT_SET] =
190       g_signal_new ("parent-set", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
191       G_STRUCT_OFFSET (GstObjectClass, parent_set), NULL, NULL,
192       g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_OBJECT);
193
194   /**
195    * GstObject::parent-unset:
196    * @gstobject: a #GstObject
197    * @parent: the old parent
198    *
199    * Emitted when the parent of an object is unset.
200    */
201   gst_object_signals[PARENT_UNSET] =
202       g_signal_new ("parent-unset", G_TYPE_FROM_CLASS (klass),
203       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstObjectClass, parent_unset), NULL,
204       NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_OBJECT);
205
206 #ifndef GST_DISABLE_LOADSAVE
207   /**
208    * GstObject::object-saved:
209    * @gstobject: a #GstObject
210    * @xml_node: the xmlNodePtr of the parent node
211    *
212    * Trigered whenever a new object is saved to XML. You can connect to this
213    * signal to insert custom XML tags into the core XML.
214    */
215   /* FIXME This should be the GType of xmlNodePtr instead of G_TYPE_POINTER
216    *       (if libxml would use GObject)
217    */
218   gst_object_signals[OBJECT_SAVED] =
219       g_signal_new ("object-saved", G_TYPE_FROM_CLASS (klass),
220       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstObjectClass, object_saved), NULL,
221       NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
222
223   klass->restore_thyself = gst_object_real_restore_thyself;
224 #endif
225
226   /**
227    * GstObject::deep-notify:
228    * @gstobject: a #GstObject
229    * @prop_object: the object that originated the signal
230    * @prop: the property that changed
231    *
232    * The deep notify signal is used to be notified of property changes. It is
233    * typically attached to the toplevel bin to receive notifications from all
234    * the elements contained in that bin.
235    */
236   gst_object_signals[DEEP_NOTIFY] =
237       g_signal_new ("deep-notify", G_TYPE_FROM_CLASS (klass),
238       G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
239       G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (GstObjectClass, deep_notify), NULL,
240       NULL, gst_marshal_VOID__OBJECT_PARAM, G_TYPE_NONE, 2, GST_TYPE_OBJECT,
241       G_TYPE_PARAM);
242
243   klass->path_string_separator = "/";
244   klass->lock = g_new0 (GStaticRecMutex, 1);
245   g_static_rec_mutex_init (klass->lock);
246
247   klass->signal_object = g_object_newv (gst_signal_object_get_type (), 0, NULL);
248
249   /* see the comments at gst_object_dispatch_properties_changed */
250   gobject_class->dispatch_properties_changed
251       = GST_DEBUG_FUNCPTR (gst_object_dispatch_properties_changed);
252
253   gobject_class->dispose = gst_object_dispose;
254   gobject_class->finalize = gst_object_finalize;
255 }
256
257 static void
258 gst_object_init (GstObject * object)
259 {
260   object->lock = g_mutex_new ();
261   object->parent = NULL;
262   object->name = NULL;
263   GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "%p new", object);
264
265 #ifndef GST_DISABLE_TRACE
266   gst_alloc_trace_new (_gst_object_trace, object);
267 #endif
268
269   object->flags = 0;
270   GST_OBJECT_FLAG_SET (object, GST_OBJECT_FLOATING);
271 }
272
273 /**
274  * gst_object_ref:
275  * @object: a #GstObject to reference
276  *
277  * Increments the reference count on @object. This function
278  * does not take the lock on @object because it relies on
279  * atomic refcounting.
280  *
281  * This object returns the input parameter to ease writing
282  * constructs like :
283  *  result = gst_object_ref (object->parent);
284  *
285  * Returns: A pointer to @object
286  */
287 gpointer
288 gst_object_ref (gpointer object)
289 {
290   g_return_val_if_fail (object != NULL, NULL);
291
292 #ifdef DEBUG_REFCOUNT
293   GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "%p ref %d->%d",
294       object,
295       ((GObject *) object)->ref_count, ((GObject *) object)->ref_count + 1);
296 #endif
297   g_object_ref (object);
298
299   return object;
300 }
301
302 /**
303  * gst_object_unref:
304  * @object: a #GstObject to unreference
305  *
306  * Decrements the reference count on @object.  If reference count hits
307  * zero, destroy @object. This function does not take the lock
308  * on @object as it relies on atomic refcounting.
309  *
310  * The unref method should never be called with the LOCK held since
311  * this might deadlock the dispose function.
312  */
313 void
314 gst_object_unref (gpointer object)
315 {
316   g_return_if_fail (object != NULL);
317   g_return_if_fail (((GObject *) object)->ref_count > 0);
318
319 #ifdef DEBUG_REFCOUNT
320   GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "%p unref %d->%d",
321       object,
322       ((GObject *) object)->ref_count, ((GObject *) object)->ref_count - 1);
323 #endif
324   g_object_unref (object);
325 }
326
327 /**
328  * gst_object_ref_sink:
329  * @object: a #GstObject to sink
330  *
331  * Increase the reference count of @object, and possibly remove the floating
332  * reference, if @object has a floating reference.
333  *
334  * In other words, if the object is floating, then this call "assumes ownership"
335  * of the floating reference, converting it to a normal reference by clearing
336  * the floating flag while leaving the reference count unchanged. If the object
337  * is not floating, then this call adds a new normal reference increasing the
338  * reference count by one.
339  *
340  * MT safe. This function grabs and releases @object lock.
341  *
342  * Since: 0.10.24
343  */
344 void
345 gst_object_ref_sink (gpointer object)
346 {
347   g_return_if_fail (GST_IS_OBJECT (object));
348
349   GST_OBJECT_LOCK (object);
350   if (G_LIKELY (GST_OBJECT_IS_FLOATING (object))) {
351     GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unsetting floating flag");
352     GST_OBJECT_FLAG_UNSET (object, GST_OBJECT_FLOATING);
353     GST_OBJECT_UNLOCK (object);
354   } else {
355     GST_OBJECT_UNLOCK (object);
356     gst_object_ref (object);
357   }
358 }
359
360 /**
361  * gst_object_sink:
362  * @object: a #GstObject to sink
363  *
364  * If @object was floating, the #GST_OBJECT_FLOATING flag is removed
365  * and @object is unreffed. When @object was not floating,
366  * this function does nothing.
367  *
368  * Any newly created object has a refcount of 1 and is floating.
369  * This function should be used when creating a new object to
370  * symbolically 'take ownership' of @object. This done by first doing a
371  * gst_object_ref() to keep a reference to @object and then gst_object_sink()
372  * to remove and unref any floating references to @object.
373  * Use gst_object_set_parent() to have this done for you.
374  *
375  * MT safe. This function grabs and releases @object lock.
376  */
377 void
378 gst_object_sink (gpointer object)
379 {
380   g_return_if_fail (GST_IS_OBJECT (object));
381
382   GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "sink");
383
384   GST_OBJECT_LOCK (object);
385   if (G_LIKELY (GST_OBJECT_IS_FLOATING (object))) {
386     GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "clear floating flag");
387     GST_OBJECT_FLAG_UNSET (object, GST_OBJECT_FLOATING);
388     GST_OBJECT_UNLOCK (object);
389     gst_object_unref (object);
390   } else {
391     GST_OBJECT_UNLOCK (object);
392   }
393 }
394
395 /**
396  * gst_object_replace:
397  * @oldobj: pointer to a place of a #GstObject to replace
398  * @newobj: a new #GstObject
399  *
400  * Unrefs the #GstObject pointed to by @oldobj, refs @newobj and
401  * puts @newobj in *@oldobj. Be carefull when calling this
402  * function, it does not take any locks. You might want to lock
403  * the object owning @oldobj pointer before calling this
404  * function.
405  *
406  * Make sure not to LOCK @oldobj because it might be unreffed
407  * which could cause a deadlock when it is disposed.
408  */
409 void
410 gst_object_replace (GstObject ** oldobj, GstObject * newobj)
411 {
412   g_return_if_fail (oldobj != NULL);
413   g_return_if_fail (*oldobj == NULL || GST_IS_OBJECT (*oldobj));
414   g_return_if_fail (newobj == NULL || GST_IS_OBJECT (newobj));
415
416 #ifdef DEBUG_REFCOUNT
417   GST_CAT_LOG (GST_CAT_REFCOUNTING, "replace %p %s (%d) with %p %s (%d)",
418       *oldobj, *oldobj ? GST_STR_NULL (GST_OBJECT_NAME (*oldobj)) : "(NONE)",
419       *oldobj ? G_OBJECT (*oldobj)->ref_count : 0,
420       newobj, newobj ? GST_STR_NULL (GST_OBJECT_NAME (newobj)) : "(NONE)",
421       newobj ? G_OBJECT (newobj)->ref_count : 0);
422 #endif
423
424   if (G_LIKELY (*oldobj != newobj)) {
425     if (newobj)
426       gst_object_ref (newobj);
427     if (*oldobj)
428       gst_object_unref (*oldobj);
429
430     *oldobj = newobj;
431   }
432 }
433
434 /* dispose is called when the object has to release all links
435  * to other objects */
436 static void
437 gst_object_dispose (GObject * object)
438 {
439   GstObject *parent;
440
441   GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
442
443   GST_OBJECT_LOCK (object);
444   if ((parent = GST_OBJECT_PARENT (object)))
445     goto have_parent;
446   GST_OBJECT_PARENT (object) = NULL;
447   GST_OBJECT_UNLOCK (object);
448
449   parent_class->dispose (object);
450
451   return;
452
453   /* ERRORS */
454 have_parent:
455   {
456     g_critical ("\nTrying to dispose object \"%s\", but it still has a "
457         "parent \"%s\".\nYou need to let the parent manage the "
458         "object instead of unreffing the object directly.\n",
459         GST_OBJECT_NAME (object), GST_OBJECT_NAME (parent));
460     GST_OBJECT_UNLOCK (object);
461     /* ref the object again to revive it in this error case */
462     gst_object_ref (object);
463     return;
464   }
465 }
466
467 /* finalize is called when the object has to free its resources */
468 static void
469 gst_object_finalize (GObject * object)
470 {
471   GstObject *gstobject = GST_OBJECT_CAST (object);
472
473   GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "finalize");
474
475   g_signal_handlers_destroy (object);
476
477   g_free (gstobject->name);
478   g_mutex_free (gstobject->lock);
479
480 #ifndef GST_DISABLE_TRACE
481   gst_alloc_trace_free (_gst_object_trace, object);
482 #endif
483
484   parent_class->finalize (object);
485 }
486
487 /* Changing a GObject property of a GstObject will result in "deep-notify"
488  * signals being emitted by the object itself, as well as in each parent
489  * object. This is so that an application can connect a listener to the
490  * top-level bin to catch property-change notifications for all contained
491  * elements.
492  *
493  * This function is not MT safe in glib < 2.8 so we need to lock it with a
494  * classwide mutex in that case.
495  *
496  * MT safe.
497  */
498 static void
499 gst_object_dispatch_properties_changed (GObject * object,
500     guint n_pspecs, GParamSpec ** pspecs)
501 {
502   GstObject *gst_object, *parent, *old_parent;
503   guint i;
504   gchar *name, *debug_name;
505
506   /* do the standard dispatching */
507   parent_class->dispatch_properties_changed (object, n_pspecs, pspecs);
508
509   gst_object = GST_OBJECT_CAST (object);
510   name = gst_object_get_name (gst_object);
511   debug_name = GST_STR_NULL (name);
512
513   /* now let the parent dispatch those, too */
514   parent = gst_object_get_parent (gst_object);
515   while (parent) {
516     for (i = 0; i < n_pspecs; i++) {
517       GST_CAT_LOG_OBJECT (GST_CAT_PROPERTIES, parent,
518           "deep notification from %s (%s)", debug_name, pspecs[i]->name);
519
520       g_signal_emit (parent, gst_object_signals[DEEP_NOTIFY],
521           g_quark_from_string (pspecs[i]->name), gst_object, pspecs[i]);
522     }
523
524     old_parent = parent;
525     parent = gst_object_get_parent (old_parent);
526     gst_object_unref (old_parent);
527   }
528   g_free (name);
529 }
530
531 /**
532  * gst_object_default_deep_notify:
533  * @object: the #GObject that signalled the notify.
534  * @orig: a #GstObject that initiated the notify.
535  * @pspec: a #GParamSpec of the property.
536  * @excluded_props: a set of user-specified properties to exclude or
537  *  NULL to show all changes.
538  *
539  * A default deep_notify signal callback for an object. The user data
540  * should contain a pointer to an array of strings that should be excluded
541  * from the notify. The default handler will print the new value of the property
542  * using g_print.
543  *
544  * MT safe. This function grabs and releases @object's LOCK for getting its
545  *          path string.
546  */
547 void
548 gst_object_default_deep_notify (GObject * object, GstObject * orig,
549     GParamSpec * pspec, gchar ** excluded_props)
550 {
551   GValue value = { 0, };        /* the important thing is that value.type = 0 */
552   gchar *str = NULL;
553   gchar *name = NULL;
554
555   if (pspec->flags & G_PARAM_READABLE) {
556     /* let's not print these out for excluded properties... */
557     while (excluded_props != NULL && *excluded_props != NULL) {
558       if (strcmp (pspec->name, *excluded_props) == 0)
559         return;
560       excluded_props++;
561     }
562     g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
563     g_object_get_property (G_OBJECT (orig), pspec->name, &value);
564
565     /* FIXME: handle flags */
566     if (G_IS_PARAM_SPEC_ENUM (pspec)) {
567       GEnumValue *enum_value;
568       GEnumClass *klass = G_ENUM_CLASS (g_type_class_ref (pspec->value_type));
569
570       enum_value = g_enum_get_value (klass, g_value_get_enum (&value));
571
572       str = g_strdup_printf ("%s (%d)", enum_value->value_nick,
573           enum_value->value);
574       g_type_class_unref (klass);
575     } else {
576       str = g_strdup_value_contents (&value);
577     }
578     name = gst_object_get_path_string (orig);
579     g_print ("%s: %s = %s\n", name, pspec->name, str);
580     g_free (name);
581     g_free (str);
582     g_value_unset (&value);
583   } else {
584     name = gst_object_get_path_string (orig);
585     g_warning ("Parameter %s not readable in %s.", pspec->name, name);
586     g_free (name);
587   }
588 }
589
590 static gboolean
591 gst_object_set_name_default (GstObject * object)
592 {
593   const gchar *type_name;
594   gint count;
595   gchar *name, *tmp;
596   GQuark q;
597
598   /* to ensure guaranteed uniqueness across threads, only one thread
599    * may ever assign a name */
600   G_LOCK (object_name_mutex);
601
602   if (!object_name_counts) {
603     g_datalist_init (&object_name_counts);
604   }
605
606   q = g_type_qname (G_OBJECT_TYPE (object));
607   count = GPOINTER_TO_INT (g_datalist_id_get_data (&object_name_counts, q));
608   g_datalist_id_set_data (&object_name_counts, q, GINT_TO_POINTER (count + 1));
609
610   G_UNLOCK (object_name_mutex);
611
612   /* GstFooSink -> foosinkN */
613   type_name = g_quark_to_string (q);
614   if (strncmp (type_name, "Gst", 3) == 0)
615     type_name += 3;
616   tmp = g_strdup_printf ("%s%d", type_name, count);
617   name = g_ascii_strdown (tmp, -1);
618   g_free (tmp);
619
620   GST_OBJECT_LOCK (object);
621   if (G_UNLIKELY (object->parent != NULL))
622     goto had_parent;
623   g_free (object->name);
624   object->name = name;
625
626   GST_OBJECT_UNLOCK (object);
627
628   return TRUE;
629
630 had_parent:
631   {
632     GST_WARNING ("parented objects can't be renamed");
633     GST_OBJECT_UNLOCK (object);
634     return FALSE;
635   }
636 }
637
638 /**
639  * gst_object_set_name:
640  * @object: a #GstObject
641  * @name:   new name of object
642  *
643  * Sets the name of @object, or gives @object a guaranteed unique
644  * name (if @name is NULL).
645  * This function makes a copy of the provided name, so the caller
646  * retains ownership of the name it sent.
647  *
648  * Returns: TRUE if the name could be set. Since Objects that have
649  * a parent cannot be renamed, this function returns FALSE in those
650  * cases.
651  *
652  * MT safe.  This function grabs and releases @object's LOCK.
653  */
654 gboolean
655 gst_object_set_name (GstObject * object, const gchar * name)
656 {
657   gboolean result;
658
659   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
660
661   GST_OBJECT_LOCK (object);
662
663   /* parented objects cannot be renamed */
664   if (G_UNLIKELY (object->parent != NULL))
665     goto had_parent;
666
667   if (name != NULL) {
668     g_free (object->name);
669     object->name = g_strdup (name);
670     GST_OBJECT_UNLOCK (object);
671     result = TRUE;
672   } else {
673     GST_OBJECT_UNLOCK (object);
674     result = gst_object_set_name_default (object);
675   }
676   /* FIXME-0.11: this misses a g_object_notify (object, "name"); unless called
677    * from gst_object_set_property.
678    * Ideally remove such custom setters (or make it static).
679    */
680   return result;
681
682   /* error */
683 had_parent:
684   {
685     GST_WARNING ("parented objects can't be renamed");
686     GST_OBJECT_UNLOCK (object);
687     return FALSE;
688   }
689 }
690
691 /**
692  * gst_object_get_name:
693  * @object: a #GstObject
694  *
695  * Returns a copy of the name of @object.
696  * Caller should g_free() the return value after usage.
697  * For a nameless object, this returns NULL, which you can safely g_free()
698  * as well.
699  *
700  * Returns: the name of @object. g_free() after usage.
701  *
702  * MT safe. This function grabs and releases @object's LOCK.
703  */
704 gchar *
705 gst_object_get_name (GstObject * object)
706 {
707   gchar *result = NULL;
708
709   g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
710
711   GST_OBJECT_LOCK (object);
712   result = g_strdup (object->name);
713   GST_OBJECT_UNLOCK (object);
714
715   return result;
716 }
717
718 /**
719  * gst_object_set_name_prefix:
720  * @object:      a #GstObject
721  * @name_prefix: new name prefix of @object
722  *
723  * Sets the name prefix of @object to @name_prefix.
724  * This function makes a copy of the provided name prefix, so the caller
725  * retains ownership of the name prefix it sent.
726  *
727  * MT safe.  This function grabs and releases @object's LOCK.
728  */
729 void
730 gst_object_set_name_prefix (GstObject * object, const gchar * name_prefix)
731 {
732   g_return_if_fail (GST_IS_OBJECT (object));
733
734   GST_OBJECT_LOCK (object);
735   g_free (object->name_prefix);
736   object->name_prefix = g_strdup (name_prefix); /* NULL gives NULL */
737   GST_OBJECT_UNLOCK (object);
738 }
739
740 /**
741  * gst_object_get_name_prefix:
742  * @object: a #GstObject
743  *
744  * Returns a copy of the name prefix of @object.
745  * Caller should g_free() the return value after usage.
746  * For a prefixless object, this returns NULL, which you can safely g_free()
747  * as well.
748  *
749  * Returns: the name prefix of @object. g_free() after usage.
750  *
751  * MT safe. This function grabs and releases @object's LOCK.
752  */
753 gchar *
754 gst_object_get_name_prefix (GstObject * object)
755 {
756   gchar *result = NULL;
757
758   g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
759
760   GST_OBJECT_LOCK (object);
761   result = g_strdup (object->name_prefix);
762   GST_OBJECT_UNLOCK (object);
763
764   return result;
765 }
766
767 /**
768  * gst_object_set_parent:
769  * @object: a #GstObject
770  * @parent: new parent of object
771  *
772  * Sets the parent of @object to @parent. The object's reference count will
773  * be incremented, and any floating reference will be removed (see gst_object_sink()).
774  *
775  * This function causes the parent-set signal to be emitted when the parent
776  * was successfully set.
777  *
778  * Returns: TRUE if @parent could be set or FALSE when @object
779  * already had a parent or @object and @parent are the same.
780  *
781  * MT safe. Grabs and releases @object's LOCK.
782  */
783 gboolean
784 gst_object_set_parent (GstObject * object, GstObject * parent)
785 {
786   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
787   g_return_val_if_fail (GST_IS_OBJECT (parent), FALSE);
788   g_return_val_if_fail (object != parent, FALSE);
789
790   GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
791       "set parent (ref and sink)");
792
793   GST_OBJECT_LOCK (object);
794   if (G_UNLIKELY (object->parent != NULL))
795     goto had_parent;
796
797   /* sink object, we don't call our own function because we don't
798    * need to release/acquire the lock needlessly or touch the refcount
799    * in the floating case. */
800   object->parent = parent;
801   if (G_LIKELY (GST_OBJECT_IS_FLOATING (object))) {
802     GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unsetting floating flag");
803     GST_OBJECT_FLAG_UNSET (object, GST_OBJECT_FLOATING);
804     GST_OBJECT_UNLOCK (object);
805   } else {
806     GST_OBJECT_UNLOCK (object);
807     gst_object_ref (object);
808   }
809
810   g_signal_emit (object, gst_object_signals[PARENT_SET], 0, parent);
811
812   return TRUE;
813
814   /* ERROR handling */
815 had_parent:
816   {
817     GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
818         "set parent failed, object already had a parent");
819     GST_OBJECT_UNLOCK (object);
820     return FALSE;
821   }
822 }
823
824 /**
825  * gst_object_get_parent:
826  * @object: a #GstObject
827  *
828  * Returns the parent of @object. This function increases the refcount
829  * of the parent object so you should gst_object_unref() it after usage.
830  *
831  * Returns: parent of @object, this can be NULL if @object has no
832  *   parent. unref after usage.
833  *
834  * MT safe. Grabs and releases @object's LOCK.
835  */
836 GstObject *
837 gst_object_get_parent (GstObject * object)
838 {
839   GstObject *result = NULL;
840
841   g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
842
843   GST_OBJECT_LOCK (object);
844   result = object->parent;
845   if (G_LIKELY (result))
846     gst_object_ref (result);
847   GST_OBJECT_UNLOCK (object);
848
849   return result;
850 }
851
852 /**
853  * gst_object_unparent:
854  * @object: a #GstObject to unparent
855  *
856  * Clear the parent of @object, removing the associated reference.
857  * This function decreases the refcount of @object.
858  *
859  * MT safe. Grabs and releases @object's lock.
860  */
861 void
862 gst_object_unparent (GstObject * object)
863 {
864   GstObject *parent;
865
866   g_return_if_fail (GST_IS_OBJECT (object));
867
868   GST_OBJECT_LOCK (object);
869   parent = object->parent;
870
871   if (G_LIKELY (parent != NULL)) {
872     GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unparent");
873     object->parent = NULL;
874     GST_OBJECT_UNLOCK (object);
875
876     g_signal_emit (object, gst_object_signals[PARENT_UNSET], 0, parent);
877
878     gst_object_unref (object);
879   } else {
880     GST_OBJECT_UNLOCK (object);
881   }
882 }
883
884 /**
885  * gst_object_has_ancestor:
886  * @object: a #GstObject to check
887  * @ancestor: a #GstObject to check as ancestor
888  *
889  * Check if @object has an ancestor @ancestor somewhere up in
890  * the hierarchy.
891  *
892  * Returns: TRUE if @ancestor is an ancestor of @object.
893  *
894  * MT safe. Grabs and releases @object's locks.
895  */
896 gboolean
897 gst_object_has_ancestor (GstObject * object, GstObject * ancestor)
898 {
899   GstObject *parent, *tmp;
900
901   if (!ancestor || !object)
902     return FALSE;
903
904   parent = gst_object_ref (object);
905   do {
906     if (parent == ancestor) {
907       gst_object_unref (parent);
908       return TRUE;
909     }
910
911     tmp = gst_object_get_parent (parent);
912     gst_object_unref (parent);
913     parent = tmp;
914   } while (parent);
915
916   return FALSE;
917 }
918
919 /**
920  * gst_object_check_uniqueness:
921  * @list: a list of #GstObject to check through
922  * @name: the name to search for
923  *
924  * Checks to see if there is any object named @name in @list. This function
925  * does not do any locking of any kind. You might want to protect the
926  * provided list with the lock of the owner of the list. This function
927  * will lock each #GstObject in the list to compare the name, so be
928  * carefull when passing a list with a locked object.
929  *
930  * Returns: TRUE if a #GstObject named @name does not appear in @list,
931  * FALSE if it does.
932  *
933  * MT safe. Grabs and releases the LOCK of each object in the list.
934  */
935 gboolean
936 gst_object_check_uniqueness (GList * list, const gchar * name)
937 {
938   gboolean result = TRUE;
939
940   g_return_val_if_fail (name != NULL, FALSE);
941
942   for (; list; list = g_list_next (list)) {
943     GstObject *child;
944     gboolean eq;
945
946     child = GST_OBJECT_CAST (list->data);
947
948     GST_OBJECT_LOCK (child);
949     eq = strcmp (GST_OBJECT_NAME (child), name) == 0;
950     GST_OBJECT_UNLOCK (child);
951
952     if (G_UNLIKELY (eq)) {
953       result = FALSE;
954       break;
955     }
956   }
957   return result;
958 }
959
960
961 #ifndef GST_DISABLE_LOADSAVE
962 /**
963  * gst_object_save_thyself:
964  * @object: a #GstObject to save
965  * @parent: The parent XML node to save @object into
966  *
967  * Saves @object into the parent XML node.
968  *
969  * Returns: the new xmlNodePtr with the saved object
970  */
971 xmlNodePtr
972 gst_object_save_thyself (GstObject * object, xmlNodePtr parent)
973 {
974   GstObjectClass *oclass;
975
976   g_return_val_if_fail (GST_IS_OBJECT (object), parent);
977   g_return_val_if_fail (parent != NULL, parent);
978
979   oclass = GST_OBJECT_GET_CLASS (object);
980
981   if (oclass->save_thyself)
982     oclass->save_thyself (object, parent);
983
984   g_signal_emit (object, gst_object_signals[OBJECT_SAVED], 0, parent);
985
986   return parent;
987 }
988
989 /**
990  * gst_object_restore_thyself:
991  * @object: a #GstObject to load into
992  * @self: The XML node to load @object from
993  *
994  * Restores @object with the data from the parent XML node.
995  */
996 void
997 gst_object_restore_thyself (GstObject * object, xmlNodePtr self)
998 {
999   GstObjectClass *oclass;
1000
1001   g_return_if_fail (GST_IS_OBJECT (object));
1002   g_return_if_fail (self != NULL);
1003
1004   oclass = GST_OBJECT_GET_CLASS (object);
1005
1006   if (oclass->restore_thyself)
1007     oclass->restore_thyself (object, self);
1008 }
1009
1010 static void
1011 gst_object_real_restore_thyself (GstObject * object, xmlNodePtr self)
1012 {
1013   g_return_if_fail (GST_IS_OBJECT (object));
1014   g_return_if_fail (self != NULL);
1015
1016   gst_class_signal_emit_by_name (object, "object_loaded", self);
1017 }
1018 #endif /* GST_DISABLE_LOADSAVE */
1019
1020 static void
1021 gst_object_set_property (GObject * object, guint prop_id,
1022     const GValue * value, GParamSpec * pspec)
1023 {
1024   GstObject *gstobject;
1025
1026   gstobject = GST_OBJECT_CAST (object);
1027
1028   switch (prop_id) {
1029     case ARG_NAME:
1030       gst_object_set_name (gstobject, g_value_get_string (value));
1031       break;
1032     default:
1033       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1034       break;
1035   }
1036 }
1037
1038 static void
1039 gst_object_get_property (GObject * object, guint prop_id,
1040     GValue * value, GParamSpec * pspec)
1041 {
1042   GstObject *gstobject;
1043
1044   gstobject = GST_OBJECT_CAST (object);
1045
1046   switch (prop_id) {
1047     case ARG_NAME:
1048       g_value_take_string (value, gst_object_get_name (gstobject));
1049       break;
1050     default:
1051       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1052       break;
1053   }
1054 }
1055
1056 /**
1057  * gst_object_get_path_string:
1058  * @object: a #GstObject
1059  *
1060  * Generates a string describing the path of @object in
1061  * the object hierarchy. Only useful (or used) for debugging.
1062  *
1063  * Returns: a string describing the path of @object. You must
1064  *          g_free() the string after usage.
1065  *
1066  * MT safe. Grabs and releases the #GstObject's LOCK for all objects
1067  *          in the hierarchy.
1068  */
1069 gchar *
1070 gst_object_get_path_string (GstObject * object)
1071 {
1072   GSList *parentage;
1073   GSList *parents;
1074   void *parent;
1075   gchar *prevpath, *path;
1076   const gchar *typename;
1077   gchar *component;
1078   gchar *separator;
1079
1080   /* ref object before adding to list */
1081   gst_object_ref (object);
1082   parentage = g_slist_prepend (NULL, object);
1083
1084   path = g_strdup ("");
1085
1086   /* first walk the object hierarchy to build a list of the parents,
1087    * be carefull here with refcounting. */
1088   do {
1089     if (GST_IS_OBJECT (object)) {
1090       parent = gst_object_get_parent (object);
1091       /* add parents to list, refcount remains increased while
1092        * we handle the object */
1093       if (parent)
1094         parentage = g_slist_prepend (parentage, parent);
1095     } else {
1096       break;
1097     }
1098     object = parent;
1099   } while (object != NULL);
1100
1101   /* then walk the parent list and print them out. we need to
1102    * decrease the refcounting on each element after we handled
1103    * it. */
1104   for (parents = parentage; parents; parents = g_slist_next (parents)) {
1105     if (G_IS_OBJECT (parents->data)) {
1106       typename = G_OBJECT_TYPE_NAME (parents->data);
1107     } else {
1108       typename = NULL;
1109     }
1110     if (GST_IS_OBJECT (parents->data)) {
1111       GstObject *item = GST_OBJECT_CAST (parents->data);
1112       GstObjectClass *oclass = GST_OBJECT_GET_CLASS (item);
1113       gchar *objname = gst_object_get_name (item);
1114
1115       component = g_strdup_printf ("%s:%s", typename, objname);
1116       separator = oclass->path_string_separator;
1117       /* and unref now */
1118       gst_object_unref (item);
1119       g_free (objname);
1120     } else {
1121       if (typename) {
1122         component = g_strdup_printf ("%s:%p", typename, parents->data);
1123       } else {
1124         component = g_strdup_printf ("%p", parents->data);
1125       }
1126       separator = "/";
1127     }
1128
1129     prevpath = path;
1130     path = g_strjoin (separator, prevpath, component, NULL);
1131     g_free (prevpath);
1132     g_free (component);
1133   }
1134
1135   g_slist_free (parentage);
1136
1137   return path;
1138 }
1139
1140
1141 struct _GstSignalObject
1142 {
1143   GObject object;
1144 };
1145
1146 struct _GstSignalObjectClass
1147 {
1148   GObjectClass parent_class;
1149
1150   /* signals */
1151 #ifndef GST_DISABLE_LOADSAVE
1152   void (*object_loaded) (GstSignalObject * object, GstObject * new,
1153       xmlNodePtr self);
1154 #endif
1155 };
1156
1157 G_DEFINE_TYPE (GstSignalObject, gst_signal_object, G_TYPE_OBJECT);
1158
1159 static void
1160 gst_signal_object_class_init (GstSignalObjectClass * klass)
1161 {
1162   parent_class = g_type_class_peek_parent (klass);
1163
1164 #ifndef GST_DISABLE_LOADSAVE
1165   gst_signal_object_signals[SO_OBJECT_LOADED] =
1166       g_signal_new ("object-loaded", G_TYPE_FROM_CLASS (klass),
1167       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstSignalObjectClass, object_loaded),
1168       NULL, NULL, gst_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
1169       G_TYPE_OBJECT, G_TYPE_POINTER);
1170 #endif
1171 }
1172
1173 static void
1174 gst_signal_object_init (GstSignalObject * object)
1175 {
1176 }
1177
1178 /**
1179  * gst_class_signal_connect
1180  * @klass: a #GstObjectClass to attach the signal to
1181  * @name: the name of the signal to attach to
1182  * @func: the signal function
1183  * @func_data: a pointer to user data
1184  *
1185  * Connect to a class signal.
1186  *
1187  * Returns: the signal id.
1188  */
1189 guint
1190 gst_class_signal_connect (GstObjectClass * klass,
1191     const gchar * name, gpointer func, gpointer func_data)
1192 {
1193   /* [0.11] func parameter needs to be changed to a GCallback *
1194    * doing so now would be an API break. */
1195   return g_signal_connect (klass->signal_object, name, G_CALLBACK (func),
1196       func_data);
1197 }
1198
1199 #ifndef GST_DISABLE_LOADSAVE
1200 /**
1201  * gst_class_signal_emit_by_name:
1202  * @object: a #GstObject that emits the signal
1203  * @name: the name of the signal to emit
1204  * @self: data for the signal
1205  *
1206  * emits the named class signal.
1207  */
1208 void
1209 gst_class_signal_emit_by_name (GstObject * object,
1210     const gchar * name, xmlNodePtr self)
1211 {
1212   GstObjectClass *oclass;
1213
1214   oclass = GST_OBJECT_GET_CLASS (object);
1215
1216   g_signal_emit_by_name (oclass->signal_object, name, object, self);
1217 }
1218
1219 #endif /* GST_DISABLE_LOADSAVE */