From 40c4fe8fbe23cc3e3293c737969fc274dfb6c4f1 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 7 Feb 2011 13:57:39 +0530 Subject: [PATCH] discoverer: Use g_signal_connect_object instead of g_signal_connect We want to make sure the discoverer object passed to the various callbacks doesn't become invalid if a callback is pending and the object is free'd in the mean time. https://bugzilla.gnome.org/show_bug.cgi?id=641706 --- gst-libs/gst/pbutils/gstdiscoverer.c | 39 ++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index dede0b3..954b732 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -108,6 +108,12 @@ struct _GstDiscovererPrivate /* reusable queries */ GstQuery *seeking_query; + + /* Handler ids for various callbacks */ + gulong pad_added_id; + gulong pad_remove_id; + gulong element_added_id; + gulong bus_cb_id; }; #define DISCO_LOCK(dc) g_mutex_lock (dc->priv->lock); @@ -267,24 +273,28 @@ gst_discoverer_init (GstDiscoverer * dc) GST_LOG_OBJECT (dc, "Adding uridecodebin to pipeline"); gst_bin_add (dc->priv->pipeline, dc->priv->uridecodebin); - g_signal_connect (dc->priv->uridecodebin, "pad-added", - G_CALLBACK (uridecodebin_pad_added_cb), dc); - g_signal_connect (dc->priv->uridecodebin, "pad-removed", - G_CALLBACK (uridecodebin_pad_removed_cb), dc); + dc->priv->pad_added_id = + g_signal_connect_object (dc->priv->uridecodebin, "pad-added", + G_CALLBACK (uridecodebin_pad_added_cb), dc, 0); + dc->priv->pad_remove_id = + g_signal_connect_object (dc->priv->uridecodebin, "pad-removed", + G_CALLBACK (uridecodebin_pad_removed_cb), dc, 0); GST_LOG_OBJECT (dc, "Getting pipeline bus"); dc->priv->bus = gst_pipeline_get_bus ((GstPipeline *) dc->priv->pipeline); - g_signal_connect (dc->priv->bus, "message", G_CALLBACK (discoverer_bus_cb), - dc); + dc->priv->bus_cb_id = + g_signal_connect_object (dc->priv->bus, "message", + G_CALLBACK (discoverer_bus_cb), dc, 0); GST_DEBUG_OBJECT (dc, "Done initializing Discoverer"); /* This is ugly. We get the GType of decodebin2 so we can quickly detect * when a decodebin2 is added to uridecodebin so we can set the * post-stream-topology setting to TRUE */ - g_signal_connect (dc->priv->uridecodebin, "element-added", - G_CALLBACK (uridecodebin_element_added_cb), dc); + dc->priv->element_added_id = + g_signal_connect_object (dc->priv->uridecodebin, "element-added", + G_CALLBACK (uridecodebin_element_added_cb), dc, 0); tmp = gst_element_factory_make ("decodebin2", NULL); dc->priv->decodebin2_type = G_OBJECT_TYPE (tmp); gst_object_unref (tmp); @@ -308,6 +318,12 @@ discoverer_reset (GstDiscoverer * dc) gst_element_set_state ((GstElement *) dc->priv->pipeline, GST_STATE_NULL); } +#define DISCONNECT_SIGNAL(o,i) G_STMT_START{ \ + if ((i) && g_signal_handler_is_connected ((o), (i))) \ + g_signal_handler_disconnect ((o), (i)); \ + (i) = 0; \ +}G_STMT_END + static void gst_discoverer_dispose (GObject * obj) { @@ -318,9 +334,16 @@ gst_discoverer_dispose (GObject * obj) discoverer_reset (dc); if (G_LIKELY (dc->priv->pipeline)) { + /* Workaround for bug #118536 */ + DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->pad_added_id); + DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->pad_remove_id); + DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->element_added_id); + DISCONNECT_SIGNAL (dc->priv->bus, dc->priv->bus_cb_id); + /* pipeline was set to NULL in _reset */ gst_object_unref (dc->priv->pipeline); gst_object_unref (dc->priv->bus); + dc->priv->pipeline = NULL; dc->priv->uridecodebin = NULL; dc->priv->bus = NULL; -- 2.7.4