From 6dae885161d6db75af151a023f3a859e04fad7d2 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Sun, 13 Jul 2014 16:59:15 +0200 Subject: [PATCH] source: Atomically change the probe ID Avoiding races where the probe would be removed 2 times Co-Authored by: Thibault Saunier --- gnl/gnlsource.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/gnl/gnlsource.c b/gnl/gnlsource.c index d1ee8c75ac..2c8122cabb 100644 --- a/gnl/gnlsource.c +++ b/gnl/gnlsource.c @@ -55,7 +55,7 @@ struct _GnlSourcePrivate gulong padremovedid; /* signal handler for element pad-removed signal */ gulong padaddedid; /* signal handler for element pad-added signal */ - gulong probeid; /* source pad probe id */ + gint probeid; /* source pad probe id */ gboolean pendingblock; /* We have a pending pad_block */ gboolean is_blocked; /* We already got blocked */ @@ -161,6 +161,20 @@ gnl_source_dispose (GObject * object) G_OBJECT_CLASS (parent_class)->dispose (object); } +static void +_remove_pad_probe (GnlSource * source, GstPad * pad) +{ + gint tmp_probe_id; + + tmp_probe_id = source->priv->probeid; + if (g_atomic_int_compare_and_exchange (&source->priv->probeid, + tmp_probe_id, 0)) { + if (tmp_probe_id) + gst_pad_remove_probe (pad, tmp_probe_id); + } + +} + static void element_pad_added_cb (GstElement * element G_GNUC_UNUSED, GstPad * pad, GnlSource * source) @@ -219,11 +233,7 @@ element_pad_removed_cb (GstElement * element G_GNUC_UNUSED, GstPad * pad, GST_DEBUG_OBJECT (source, "Clearing up ghostpad"); priv->is_blocked = FALSE; - if (priv->probeid) { - gst_pad_remove_probe (pad, priv->probeid); - priv->probeid = 0; - } - + _remove_pad_probe (source, pad); gnl_object_ghost_pad_set_target (GNL_OBJECT (source), gnlobject->srcpad, NULL); @@ -315,10 +325,7 @@ ghost_seek_pad (GnlSource * source) } priv->is_blocked = FALSE; - if (priv->probeid) { - gst_pad_remove_probe (pad, priv->probeid); - priv->probeid = 0; - } + _remove_pad_probe (source, pad); gst_element_no_more_pads (GST_ELEMENT (source)); priv->pendingblock = FALSE; @@ -549,10 +556,7 @@ gnl_source_cleanup (GnlObject * object) GstPad *target = gst_ghost_pad_get_target ((GstGhostPad *) object->srcpad); if (target) { - if (priv->probeid) { - gst_pad_remove_probe (target, priv->probeid); - priv->probeid = 0; - } + _remove_pad_probe (source, target); gst_object_unref (target); }