From d8ca412cd96399e8553790c1b0c4572345eb8a74 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 2 Jul 2014 17:33:35 +0200 Subject: [PATCH] composition: Add objects to the pending IO list in a GSource This way we make sure we do not manipulate our children from another thread than the dedicated one. --- gnl/gnlcomposition.c | 79 ++++++++++++++++++++++++++++---- tests/check/gnl/gnlcomposition.c | 2 +- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/gnl/gnlcomposition.c b/gnl/gnlcomposition.c index 43a790ee47..d2af0f3d90 100644 --- a/gnl/gnlcomposition.c +++ b/gnl/gnlcomposition.c @@ -82,6 +82,12 @@ typedef struct GstEvent *event; } SeekData; +typedef struct +{ + GnlComposition *comp; + GnlObject *object; +} ChildIOData; + struct _GnlCompositionPrivate { gboolean dispose_has_run; @@ -530,9 +536,18 @@ _add_initialize_stack_gsource (GnlComposition * comp) MAIN_CONTEXT_UNLOCK (comp); } -static gboolean -remove_object_handler (GnlComposition * comp, GnlObject * object) +static void +_free_child_io_data (gpointer childio) { + g_slice_free (ChildIOData, childio); +} + +static void +_remove_object_func (ChildIOData * childio) +{ + GnlComposition *comp = childio->comp; + GnlObject *object = childio->object; + GnlCompositionPrivate *priv = comp->priv; GnlCompositionEntry *entry; GnlObject *in_pending_io; @@ -548,14 +563,14 @@ remove_object_handler (GnlComposition * comp, GnlObject * object) g_hash_table_remove (priv->pending_io, object); COMP_OBJECTS_UNLOCK (comp); - return TRUE; + return; } GST_ERROR_OBJECT (comp, "Object %" GST_PTR_FORMAT " is " " not in the composition", object); COMP_OBJECTS_UNLOCK (comp); - return FALSE; + return; } if (in_pending_io) { @@ -563,19 +578,43 @@ remove_object_handler (GnlComposition * comp, GnlObject * object) " for removal", object); COMP_OBJECTS_UNLOCK (comp); - return FALSE; + return; } g_hash_table_add (priv->pending_io, object); COMP_OBJECTS_UNLOCK (comp); - return TRUE; + return; +} + +static void +_add_remove_object_gsource (GnlComposition * comp, GnlObject * object) +{ + ChildIOData *childio = g_slice_new0 (ChildIOData); + + childio->comp = comp; + childio->object = object; + + MAIN_CONTEXT_LOCK (comp); + g_main_context_invoke_full (comp->priv->mcontext, G_PRIORITY_HIGH, + (GSourceFunc) _remove_object_func, childio, _free_child_io_data); + MAIN_CONTEXT_UNLOCK (comp); } static gboolean -add_object_handler (GnlComposition * comp, GnlObject * object) +remove_object_handler (GnlComposition * comp, GnlObject * object) { + _add_remove_object_gsource (comp, object); + + return TRUE; +} + +static void +_add_object_func (ChildIOData * childio) +{ + GnlComposition *comp = childio->comp; + GnlObject *object = childio->object; GnlCompositionPrivate *priv = comp->priv; GnlCompositionEntry *entry; GnlObject *in_pending_io; @@ -589,7 +628,7 @@ add_object_handler (GnlComposition * comp, GnlObject * object) " already in the composition", object); COMP_OBJECTS_UNLOCK (comp); - return FALSE; + return; } if (in_pending_io) { @@ -597,13 +636,35 @@ add_object_handler (GnlComposition * comp, GnlObject * object) " for addition", object); COMP_OBJECTS_UNLOCK (comp); - return FALSE; + return; } g_hash_table_add (priv->pending_io, object); COMP_OBJECTS_UNLOCK (comp); + return; +} + +static void +_add_add_object_gsource (GnlComposition * comp, GnlObject * object) +{ + ChildIOData *childio = g_slice_new0 (ChildIOData); + + childio->comp = comp; + childio->object = object; + + MAIN_CONTEXT_LOCK (comp); + g_main_context_invoke_full (comp->priv->mcontext, G_PRIORITY_HIGH, + (GSourceFunc) _add_object_func, childio, _free_child_io_data); + MAIN_CONTEXT_UNLOCK (comp); +} + +static gboolean +add_object_handler (GnlComposition * comp, GnlObject * object) +{ + _add_add_object_gsource (comp, object); + return TRUE; } diff --git a/tests/check/gnl/gnlcomposition.c b/tests/check/gnl/gnlcomposition.c index 8a8b90991a..ef09b4f093 100644 --- a/tests/check/gnl/gnlcomposition.c +++ b/tests/check/gnl/gnlcomposition.c @@ -187,7 +187,7 @@ GST_START_TEST (test_remove_invalid_object) source2 = gst_element_factory_make ("gnlsource", "source2"); gnl_composition_add (composition, source1); - fail_if (gnl_composition_remove (composition, source2)); + gnl_composition_remove (composition, source2); fail_unless (gnl_composition_remove (composition, source1)); gst_object_unref (composition);