summaryrefslogtreecommitdiff
path: root/ext/gtk
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2016-02-16 19:59:13 +1100
committerMatthew Waters <matthew@centricular.com>2016-02-16 20:09:08 +1100
commitaaacc9fe54ec644803f402d5ad48e19aab41aad9 (patch)
tree1fdd24d77e2c51fd730e171416e19056ab61ae27 /ext/gtk
parentcaafdd8ca2a34bcbd3ea80b208f691d74a2b38a5 (diff)
downloadgstreamer-plugins-good-aaacc9fe54ec644803f402d5ad48e19aab41aad9.tar.gz
gtk(gl)sink: remove the signal handlers on finalize
It's possible that the sink element will be freed before the widget is destroyed. When the widget was eventually destroyed, it was attempting to access member variables of the freed sink struct which resulted in undefined behaviour. Fix by disconnecting our signal on finalize. https://bugzilla.gnome.org/show_bug.cgi?id=762098
Diffstat (limited to 'ext/gtk')
-rw-r--r--ext/gtk/gstgtkbasesink.c13
-rw-r--r--ext/gtk/gstgtkbasesink.h2
2 files changed, 12 insertions, 3 deletions
diff --git a/ext/gtk/gstgtkbasesink.c b/ext/gtk/gstgtkbasesink.c
index e19294065..f0019bf26 100644
--- a/ext/gtk/gstgtkbasesink.c
+++ b/ext/gtk/gstgtkbasesink.c
@@ -141,9 +141,16 @@ gst_gtk_base_sink_init (GstGtkBaseSink * gtk_sink)
static void
gst_gtk_base_sink_finalize (GObject * object)
{
- GstGtkBaseSink *gtk_sink = GST_GTK_BASE_SINK (object);;
+ GstGtkBaseSink *gtk_sink = GST_GTK_BASE_SINK (object);
+
+ GST_OBJECT_LOCK (gtk_sink);
+ if (gtk_sink->window && gtk_sink->window_destroy_id)
+ g_signal_handler_disconnect (gtk_sink->window, gtk_sink->window_destroy_id);
+ if (gtk_sink->widget && gtk_sink->widget_destroy_id)
+ g_signal_handler_disconnect (gtk_sink->widget, gtk_sink->widget_destroy_id);
g_clear_object (&gtk_sink->widget);
+ GST_OBJECT_UNLOCK (gtk_sink);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -194,7 +201,7 @@ gst_gtk_base_sink_get_widget (GstGtkBaseSink * gtk_sink)
/* Take the floating ref, other wise the destruction of the container will
* make this widget disapear possibly before we are done. */
gst_object_ref_sink (gtk_sink->widget);
- g_signal_connect (gtk_sink->widget, "destroy",
+ gtk_sink->widget_destroy_id = g_signal_connect (gtk_sink->widget, "destroy",
G_CALLBACK (widget_destroy_cb), gtk_sink);
/* back pointer */
@@ -316,7 +323,7 @@ gst_gtk_base_sink_start_on_main (GstBaseSink * bsink)
gtk_window_set_default_size (GTK_WINDOW (gst_sink->window), 640, 480);
gtk_window_set_title (GTK_WINDOW (gst_sink->window), klass->window_title);
gtk_container_add (GTK_CONTAINER (gst_sink->window), toplevel);
- g_signal_connect (gst_sink->window, "destroy",
+ gst_sink->window_destroy_id = g_signal_connect (gst_sink->window, "destroy",
G_CALLBACK (window_destroy_cb), gst_sink);
}
diff --git a/ext/gtk/gstgtkbasesink.h b/ext/gtk/gstgtkbasesink.h
index 7260cd5a7..ef8c28495 100644
--- a/ext/gtk/gstgtkbasesink.h
+++ b/ext/gtk/gstgtkbasesink.h
@@ -69,6 +69,8 @@ struct _GstGtkBaseSink
GBinding *bind_ignore_alpha;
GtkWidget *window;
+ gulong widget_destroy_id;
+ gulong window_destroy_id;
};
/**