diff options
author | Edward Hervey <bilboed@bilboed.com> | 2009-08-24 12:08:45 +0200 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2009-08-24 12:08:45 +0200 |
commit | 79b0699a3a483c9de92782a78350d2257b2c8611 (patch) | |
tree | 884406be83d9a067d6e1f665d52113e80190b41e | |
parent | fa94befe2611c41158d993858da71fc7ea27739f (diff) |
gnlsource: Make the pad removal code non-racy.
Previously we were checking whether (1) there was a ghostpad and (2) whether
the target was the pad being removed.
The problem was that the following racyness can happen:
1. A pad gets added and controlled
2. The pad gets removed before having outputted any data (and therefore the
ghostpad isn't created).
3. There's no ghostpad... and therefore we don't properly reset ourselves.
-rw-r--r-- | gnl/gnlsource.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/gnl/gnlsource.c b/gnl/gnlsource.c index 28035b7..29b9c2a 100644 --- a/gnl/gnlsource.c +++ b/gnl/gnlsource.c @@ -246,25 +246,29 @@ static void element_pad_removed_cb (GstElement * element G_GNUC_UNUSED, GstPad * pad, GnlSource * source) { - GST_DEBUG_OBJECT (source, "pad %s:%s", GST_DEBUG_PAD_NAME (pad)); + GST_DEBUG_OBJECT (source, "pad %s:%s (controlled pad %s:%s)", + GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (source->priv->ghostedpad)); + + if (pad == source->priv->ghostedpad) { + GST_DEBUG_OBJECT (source, + "The removed pad is the controlled pad, clearing up"); - if (source->priv->ghostpad) { - GstPad *target = - gst_ghost_pad_get_target (GST_GHOST_PAD (source->priv->ghostpad)); + if (source->priv->ghostpad) { + GST_DEBUG_OBJECT (source, "Clearing up ghostpad"); - if (target == pad) { - gst_pad_set_blocked_async (target, FALSE, + gst_pad_set_blocked_async (pad, FALSE, (GstPadBlockCallback) pad_blocked_cb, source); gnl_object_remove_ghost_pad ((GnlObject *) source, source->priv->ghostpad); source->priv->ghostpad = NULL; - source->priv->pendingblock = FALSE; - gst_object_unref (target); - } else { - GST_DEBUG_OBJECT (source, "The removed pad wasn't our ghostpad target"); } + + source->priv->pendingblock = FALSE; + source->priv->ghostedpad = NULL; + } else { + GST_DEBUG_OBJECT (source, "The removed pad is NOT our controlled pad"); } } @@ -576,6 +580,7 @@ gnl_source_change_state (GstElement * element, GstStateChange transition) source->priv->ghostpad); source->priv->ghostpad = NULL; source->priv->ghostedpad = NULL; + source->priv->pendingblock = FALSE; } default: break; |