summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <bilboed@bilboed.com>2009-08-24 12:08:45 +0200
committerEdward Hervey <bilboed@bilboed.com>2009-08-24 12:08:45 +0200
commit79b0699a3a483c9de92782a78350d2257b2c8611 (patch)
tree884406be83d9a067d6e1f665d52113e80190b41e
parentfa94befe2611c41158d993858da71fc7ea27739f (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.c25
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;