From 3fe10e0bb1a7d6d9ad1f28ab50d609d2a0af55fb Mon Sep 17 00:00:00 2001 From: Stephen Kennedy Date: Wed, 29 Sep 2010 10:56:48 +0100 Subject: [PATCH] ClutterAnimator doesn't ref timeline properly ClutterAnimator currently has a number of bugs related to its referencing of its internal timeline. 1) The default timeline created in _init is not unreffed (it appears the programmer has wrongly thought ClutterTimeline has a floating reference based on the use of g_object_ref_sink in _set_timeline) 2) The timeline and slave_timeline vars are unreffed in finalize instead of dispose 3) The signal handlers set up in _set_timeline are not disconnected when the animator is disposed http://bugzilla.clutter-project.org/show_bug.cgi?id=2347 Signed-off-by: Emmanuele Bassi --- clutter/clutter-animator.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/clutter/clutter-animator.c b/clutter/clutter-animator.c index f43ac99e9..b6a31500f 100644 --- a/clutter/clutter-animator.c +++ b/clutter/clutter-animator.c @@ -434,6 +434,18 @@ clutter_animator_key_free (gpointer boxed) g_slice_free (ClutterAnimatorKey, key); } +static void +clutter_animator_dispose (GObject *object) +{ + ClutterAnimator *animator = CLUTTER_ANIMATOR (object); + ClutterAnimatorPrivate *priv = animator->priv; + + clutter_animator_set_timeline (animator, NULL); + g_object_unref (priv->slave_timeline); + + G_OBJECT_CLASS (clutter_animator_parent_class)->dispose (object); +} + static void clutter_animator_finalize (GObject *object) { @@ -444,9 +456,6 @@ clutter_animator_finalize (GObject *object) g_list_free (priv->score); priv->score = NULL; - g_object_unref (priv->timeline); - g_object_unref (priv->slave_timeline); - g_hash_table_destroy (priv->properties); G_OBJECT_CLASS (clutter_animator_parent_class)->finalize (object); @@ -1049,7 +1058,7 @@ clutter_animator_set_timeline (ClutterAnimator *animator, priv->timeline = timeline; if (timeline != NULL) { - g_object_ref_sink (priv->timeline); + g_object_ref (priv->timeline); g_signal_connect (priv->timeline, "new-frame", G_CALLBACK (animation_animator_new_frame), @@ -1764,6 +1773,7 @@ clutter_animator_class_init (ClutterAnimatorClass *klass) gobject_class->set_property = clutter_animator_set_property; gobject_class->get_property = clutter_animator_get_property; + gobject_class->dispose = clutter_animator_dispose; gobject_class->finalize = clutter_animator_finalize; /** @@ -1804,6 +1814,7 @@ static void clutter_animator_init (ClutterAnimator *animator) { ClutterAnimatorPrivate *priv; + ClutterTimeline *timeline; animator->priv = priv = CLUTTER_ANIMATOR_GET_PRIVATE (animator); @@ -1812,7 +1823,9 @@ clutter_animator_init (ClutterAnimator *animator) prop_actor_key_free, property_iter_free); - clutter_animator_set_timeline (animator, clutter_timeline_new (2000)); + timeline = clutter_timeline_new (2000); + clutter_animator_set_timeline (animator, timeline); + g_object_unref (timeline); priv->slave_timeline = clutter_timeline_new (10000); }