aggregator: Avoid destroying sources we do not own
authorThibault Saunier <tsaunier@gnome.org>
Mon, 30 Jun 2014 10:22:07 +0000 (12:22 +0200)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 2 Dec 2017 15:10:25 +0000 (15:10 +0000)
+ 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
tests/check/libs/aggregator.c

index fc949ea..0d80f3c 100644 (file)
@@ -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
index 007208c..1b9c978 100644 (file)
@@ -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);