From a3c4a3201a705eb1934ceeea34d1ca42d4571c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Graff?= Date: Mon, 11 Jan 2010 11:38:32 +0100 Subject: [PATCH] tee: make release_pad threadsafe Protect the ->removed field with the object lock as well. Take the DYN lock earlier so that we can mark the pad removed and avoid a race in pad_alloc. Fixes #606435 --- plugins/elements/gsttee.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/plugins/elements/gsttee.c b/plugins/elements/gsttee.c index 1d050e0376..a639b04bb3 100644 --- a/plugins/elements/gsttee.c +++ b/plugins/elements/gsttee.c @@ -346,26 +346,27 @@ gst_tee_release_pad (GstElement * element, GstPad * pad) GST_DEBUG_OBJECT (tee, "releasing pad"); + /* wait for pending pad_alloc to finish */ + GST_TEE_DYN_LOCK (tee); + data = g_object_get_qdata (G_OBJECT (pad), push_data); + GST_OBJECT_LOCK (tee); + /* mark the pad as removed so that future pad_alloc fails with NOT_LINKED. */ + data->removed = TRUE; if (tee->allocpad == pad) { tee->allocpad = NULL; changed = TRUE; } GST_OBJECT_UNLOCK (tee); - if (changed) { - g_object_notify (G_OBJECT (tee), "alloc-pad"); - } - - /* wait for pending pad_alloc to finish */ - GST_TEE_DYN_LOCK (tee); - /* mark the pad as removed so that future pad_alloc fails with NOT_LINKED. */ - data = g_object_get_qdata (G_OBJECT (pad), push_data); - data->removed = TRUE; gst_pad_set_active (pad, FALSE); gst_element_remove_pad (GST_ELEMENT_CAST (tee), pad); GST_TEE_DYN_UNLOCK (tee); + + if (changed) { + g_object_notify (G_OBJECT (tee), "alloc-pad"); + } } static void @@ -495,7 +496,7 @@ retry: *buf = NULL; goto retry; } - if (res == GST_FLOW_OK) { + if (!data->removed && res == GST_FLOW_OK) { GST_DEBUG_OBJECT (tee, "we have a buffer on pad %s:%s", GST_DEBUG_PAD_NAME (pad)); /* we have a buffer, keep the pad for later and exit the loop. */