From 481476c439b85806a557c791bfe8a81065b384d3 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 30 Jun 2014 12:22:07 +0200 Subject: [PATCH] aggregator: Avoid destroying sources we do not own + Unref the maincontext in a new dispose function + Make sure to remove all sources on dispose https://bugzilla.gnome.org/show_bug.cgi?id=732445 --- libs/gst/base/gstaggregator.c | 39 +++++++++++++++++++++++++++++++-------- tests/check/libs/aggregator.c | 4 ++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/libs/gst/base/gstaggregator.c b/libs/gst/base/gstaggregator.c index fc949ea..0d80f3c 100644 --- a/libs/gst/base/gstaggregator.c +++ b/libs/gst/base/gstaggregator.c @@ -163,6 +163,7 @@ struct _GstAggregatorPrivate * we can not add any source, avoiding: * "g_source_attach: assertion '!SOURCE_DESTROYED (source)' failed" */ GMutex mcontext_lock; + GList *gsources; gboolean send_stream_start; gboolean send_segment; @@ -375,17 +376,22 @@ _push_eos (GstAggregator * self) gst_pad_push_event (self->srcpad, gst_event_new_eos ()); } + +static void +_destroy_gsource (GSource * source) +{ + g_source_destroy (source); + g_source_unref (source); +} + static void _remove_all_sources (GstAggregator * self) { - GSource *source; + GstAggregatorPrivate *priv = self->priv; MAIN_CONTEXT_LOCK (self); - while ((source = - g_main_context_find_source_by_user_data (self->priv->mcontext, - self))) { - g_source_destroy (source); - } + g_list_free_full (priv->gsources, (GDestroyNotify) _destroy_gsource); + priv->gsources = NULL; MAIN_CONTEXT_UNLOCK (self); } @@ -488,9 +494,14 @@ _start_srcpad_task (GstAggregator * self) static inline void _add_aggregate_gsource (GstAggregator * self) { + GSource *source; + GstAggregatorPrivate *priv = self->priv; + MAIN_CONTEXT_LOCK (self); - g_main_context_invoke (self->priv->mcontext, (GSourceFunc) aggregate_func, - self); + source = g_idle_source_new (); + g_source_set_callback (source, (GSourceFunc) aggregate_func, self, NULL); + priv->gsources = g_list_prepend (priv->gsources, source); + g_source_attach (source, priv->mcontext); MAIN_CONTEXT_UNLOCK (self); } @@ -1017,6 +1028,17 @@ gst_aggregator_finalize (GObject * object) G_OBJECT_CLASS (aggregator_parent_class)->finalize (object); } +static void +gst_aggregator_dispose (GObject * object) +{ + GstAggregator *self = (GstAggregator *) object; + + G_OBJECT_CLASS (aggregator_parent_class)->dispose (object); + + g_main_context_unref (self->priv->mcontext); + _remove_all_sources (self); +} + /* GObject vmethods implementations */ static void gst_aggregator_class_init (GstAggregatorClass * klass) @@ -1045,6 +1067,7 @@ gst_aggregator_class_init (GstAggregatorClass * klass) gstelement_class->change_state = GST_DEBUG_FUNCPTR (_change_state); gobject_class->finalize = gst_aggregator_finalize; + gobject_class->dispose = gst_aggregator_dispose; } static void diff --git a/tests/check/libs/aggregator.c b/tests/check/libs/aggregator.c index 007208c..1b9c978 100644 --- a/tests/check/libs/aggregator.c +++ b/tests/check/libs/aggregator.c @@ -106,7 +106,7 @@ gst_test_aggregator_aggregate (GstAggregator * aggregator) gst_iterator_free (iter); if (all_eos == TRUE) { - GST_ERROR_OBJECT (testagg, "no data available, must be EOS"); + GST_INFO_OBJECT (testagg, "no data available, must be EOS"); gst_pad_push_event (aggregator->srcpad, gst_event_new_eos ()); return GST_FLOW_EOS; } @@ -257,7 +257,7 @@ push_event (gpointer user_data) { ChainData *chain_data = (ChainData *) user_data; - GST_ERROR_OBJECT (chain_data->srcpad, "Pushing event: %" + GST_INFO_OBJECT (chain_data->srcpad, "Pushing event: %" GST_PTR_FORMAT, chain_data->event); fail_unless (gst_pad_push_event (chain_data->srcpad, chain_data->event) == TRUE); -- 2.7.4