libs/gst/controller/gstcontroller.c: Fix refcounting here too, just like we did for...
authorTim-Philipp Müller <tim@centricular.net>
Wed, 11 Oct 2006 09:13:26 +0000 (09:13 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Wed, 11 Oct 2006 09:13:26 +0000 (09:13 +0000)
Original commit message from CVS:
* libs/gst/controller/gstcontroller.c: (gst_controller_new_list):
Fix refcounting here too, just like we did for _new_valist() a few
days ago (#357180) (thanks to René Stadler). Also remove all those
'Since: 0.9' from the gtk-doc blobs.
* tests/check/libs/controller.c: (controller_refcount_new_list),
(gst_controller_suite):
Unit test for the above.

ChangeLog
libs/gst/controller/gstcontroller.c
tests/check/libs/controller.c

index f127261..af20c3e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-10-11  Tim-Philipp Müller  <tim at centricular dot net>
+
+       * libs/gst/controller/gstcontroller.c: (gst_controller_new_list):
+         Fix refcounting here too, just like we did for _new_valist() a few
+         days ago (#357180) (thanks to René Stadler). Also remove all those
+         'Since: 0.9' from the gtk-doc blobs.
+
+       * tests/check/libs/controller.c: (controller_refcount_new_list),
+       (gst_controller_suite):
+         Unit test for the above.
+
 2006-10-10  Wim Taymans  <wim@fluendo.com>
 
        Patch by: Sebastien Cote <sebas642 at yahoo dot ca>
index a749a70..b81e776 100644 (file)
@@ -448,7 +448,6 @@ gst_controller_find_controlled_property (GstController * self,
  * Creates a new GstController for the given object's properties
  *
  * Returns: the new controller.
- * Since: 0.9
  */
 GstController *
 gst_controller_new_valist (GObject * object, va_list var_args)
@@ -520,13 +519,13 @@ gst_controller_new_valist (GObject * object, va_list var_args)
  * Creates a new GstController for the given object's properties
  *
  * Returns: the new controller.
- * Since: 0.9
  */
 GstController *
 gst_controller_new_list (GObject * object, GList * list)
 {
   GstController *self;
   GstControlledProperty *prop;
+  gboolean ref_existing = TRUE;
   gchar *name;
   GList *node;
 
@@ -548,14 +547,23 @@ gst_controller_new_list (GObject * object, GList * list)
           self->object = g_object_ref (object);
           /* store the controller */
           g_object_set_qdata (object, __gst_controller_key, self);
+          ref_existing = FALSE;
         } else {
-          g_object_ref (self);
-          GST_INFO ("returning existing controller");
+          /* only want one single _ref(), even for multiple properties */
+          if (ref_existing) {
+            g_object_ref (self);
+            ref_existing = FALSE;
+            GST_INFO ("returning existing controller");
+          }
         }
         self->properties = g_list_prepend (self->properties, prop);
       }
     } else {
       GST_WARNING ("trying to control property again");
+      if (ref_existing) {
+        g_object_ref (self);
+        ref_existing = FALSE;
+      }
     }
   }
 
@@ -572,7 +580,6 @@ gst_controller_new_list (GObject * object, GList * list)
  * Creates a new GstController for the given object's properties
  *
  * Returns: the new controller.
- * Since: 0.9
  */
 GstController *
 gst_controller_new (GObject * object, ...)
@@ -597,7 +604,6 @@ gst_controller_new (GObject * object, ...)
  * Removes the given object properties from the controller
  *
  * Returns: %FALSE if one of the given property isn't handled by the controller, %TRUE otherwise
- * Since: 0.9
  */
 gboolean
 gst_controller_remove_properties_valist (GstController * self, va_list var_args)
@@ -632,7 +638,6 @@ gst_controller_remove_properties_valist (GstController * self, va_list var_args)
  * Removes the given object properties from the controller
  *
  * Returns: %FALSE if one of the given property isn't handled by the controller, %TRUE otherwise
- * Since: 0.9
  */
 gboolean
 gst_controller_remove_properties_list (GstController * self, GList * list)
@@ -670,7 +675,6 @@ gst_controller_remove_properties_list (GstController * self, GList * list)
  * Removes the given object properties from the controller
  *
  * Returns: %FALSE if one of the given property isn't handled by the controller, %TRUE otherwise
- * Since: 0.9
  */
 gboolean
 gst_controller_remove_properties (GstController * self, ...)
@@ -697,7 +701,6 @@ gst_controller_remove_properties (GstController * self, ...)
  * Set the value of given controller-handled property at a certain time.
  *
  * Returns: FALSE if the values couldn't be set (ex : properties not handled by controller), TRUE otherwise
- * Since: 0.9
  */
 gboolean
 gst_controller_set (GstController * self, gchar * property_name,
@@ -750,7 +753,6 @@ gst_controller_set (GstController * self, gchar * property_name,
  * Sets multiple timed values at once.
  *
  * Returns: %FALSE if the values couldn't be set (ex : properties not handled by controller), %TRUE otherwise
- * Since: 0.9
  */
 
 gboolean
@@ -799,7 +801,6 @@ gst_controller_set_from_list (GstController * self, gchar * property_name,
  * time.
  *
  * Returns: %FALSE if the values couldn't be unset (ex : properties not handled by controller), %TRUE otherwise
- * Since: 0.9
  */
 gboolean
 gst_controller_unset (GstController * self, gchar * property_name,
@@ -872,7 +873,6 @@ gst_controller_unset_all (GstController * self, gchar * property_name)
  * time.
  *
  * Returns: the GValue of the property at the given time, or %NULL if the property isn't handled by the controller
- * Since: 0.9
  */
 GValue *
 gst_controller_get (GstController * self, gchar * property_name,
@@ -904,7 +904,6 @@ gst_controller_get (GstController * self, gchar * property_name,
  * Free the list after done with it.
  *
  * Returns: a copy of the list, or %NULL if the property isn't handled by the controller
- * Since: 0.9
  */
 const GList *
 gst_controller_get_all (GstController * self, gchar * property_name)
@@ -934,7 +933,6 @@ gst_controller_get_all (GstController * self, gchar * property_name)
  *
  * Returns: %TRUE if the controller values could be applied to the object
  * properties, %FALSE otherwise
- * Since: 0.9
  */
 gboolean
 gst_controller_sync_values (GstController * self, GstClockTime timestamp)
@@ -1005,7 +1003,6 @@ gst_controller_sync_values (GstController * self, GstClockTime timestamp)
  * The type of the values in the array are the same as the property's type.
  *
  * Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
- * Since: 0.9
  */
 gboolean
 gst_controller_get_value_arrays (GstController * self,
@@ -1037,7 +1034,6 @@ gst_controller_get_value_arrays (GstController * self,
  * The type of the values in the array are the same as the property's type.
  *
  * Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
- * Since: 0.9
  */
 gboolean
 gst_controller_get_value_array (GstController * self, GstClockTime timestamp,
@@ -1080,7 +1076,6 @@ gst_controller_get_value_array (GstController * self, GstClockTime timestamp,
  * Sets the given interpolation mode on the given property.
  *
  * Returns: %TRUE if the property is handled by the controller, %FALSE otherwise
- * Since: 0.9
  */
 gboolean
 gst_controller_set_interpolation_mode (GstController * self,
index 11d8745..9b22231 100644 (file)
@@ -858,6 +858,84 @@ GST_START_TEST (controller_misc)
 
 GST_END_TEST;
 
+GST_START_TEST (controller_refcount_new_list)
+{
+  GstController *ctrl, *ctrl2;
+  GstElement *elem;
+  GList *list = NULL;
+
+  gst_controller_init (NULL, NULL);
+
+  /* that property should exist and should be controllable */
+  elem = gst_element_factory_make ("testmonosource", "test_source");
+  list = g_list_append (NULL, "ulong");
+  ctrl = gst_controller_new_list (G_OBJECT (elem), list);
+  fail_unless (ctrl != NULL, NULL);
+  GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+  fail_unless (G_OBJECT (ctrl)->ref_count == 1);
+  g_list_free (list);
+  g_object_unref (ctrl);
+  gst_object_unref (elem);
+
+  /* try the same property twice, make sure the refcount is still 1 */
+  elem = gst_element_factory_make ("testmonosource", "test_source");
+  list = g_list_append (NULL, "ulong");
+  list = g_list_append (list, "ulong");
+  ctrl = gst_controller_new_list (G_OBJECT (elem), list);
+  fail_unless (ctrl != NULL, NULL);
+  GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+  fail_unless (G_OBJECT (ctrl)->ref_count == 1);
+  g_list_free (list);
+  g_object_unref (ctrl);
+  gst_object_unref (elem);
+
+  /* try two properties, make sure the refcount is still 1 */
+  elem = gst_element_factory_make ("testmonosource", "test_source");
+  list = g_list_append (NULL, "ulong");
+  list = g_list_append (list, "boolean");
+  ctrl = gst_controller_new_list (G_OBJECT (elem), list);
+  fail_unless (ctrl != NULL, NULL);
+  GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+  fail_unless (G_OBJECT (ctrl)->ref_count == 1);
+  g_list_free (list);
+  g_object_unref (ctrl);
+  gst_object_unref (elem);
+
+  /* try _new_list with existing controller */
+  elem = gst_element_factory_make ("testmonosource", "test_source");
+  ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
+  fail_unless (ctrl != NULL, NULL);
+  GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+  list = g_list_append (NULL, "ulong");
+  ctrl2 = gst_controller_new_list (G_OBJECT (elem), list);
+  fail_unless (ctrl2 != NULL, NULL);
+  fail_unless (ctrl == ctrl2, NULL);
+  GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+  fail_unless (G_OBJECT (ctrl)->ref_count == 2);
+  g_list_free (list);
+  g_object_unref (ctrl);
+  g_object_unref (ctrl2);
+  gst_object_unref (elem);
+
+  /* try _new_list first and then _new */
+  elem = gst_element_factory_make ("testmonosource", "test_source");
+  list = g_list_append (NULL, "ulong");
+  ctrl = gst_controller_new_list (G_OBJECT (elem), list);
+  fail_unless (ctrl != NULL, NULL);
+  GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+  ctrl2 = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
+  fail_unless (ctrl2 != NULL, NULL);
+  fail_unless (ctrl == ctrl2, NULL);
+  GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+  fail_unless (G_OBJECT (ctrl)->ref_count == 2);
+  g_list_free (list);
+  g_object_unref (ctrl);
+  g_object_unref (ctrl2);
+  gst_object_unref (elem);
+}
+
+GST_END_TEST;
+
 static Suite *
 gst_controller_suite (void)
 {
@@ -866,6 +944,7 @@ gst_controller_suite (void)
 
   suite_add_tcase (s, tc);
   tcase_add_test (tc, controller_init);
+  tcase_add_test (tc, controller_refcount_new_list);
   tcase_add_test (tc, controller_new_fail1);
   tcase_add_test (tc, controller_new_fail2);
   tcase_add_test (tc, controller_new_fail3);