From 5d1d7d95b29a687bc91c56b9035aa0cb5f9a4e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 26 Jan 2012 14:33:12 +0100 Subject: [PATCH] caps: Store a pointer to GstCaps in GstStaticCaps ...instead of using hackish subclass of GstCaps, which also had some thread-safety problems. --- gst/gstcaps.c | 51 +++++++++++------------------------------ gst/gstcaps.h | 5 ++-- gst/gstelementfactory.c | 2 +- gst/gstregistrychunks.c | 2 +- 4 files changed, 18 insertions(+), 42 deletions(-) diff --git a/gst/gstcaps.c b/gst/gstcaps.c index 3bfe62bde5..9c1bd7f201 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -356,7 +356,6 @@ gst_static_caps_get_type (void) return staticcaps_type; } - /** * gst_static_caps_get: * @static_caps: the #GstStaticCaps to convert @@ -370,20 +369,19 @@ gst_static_caps_get_type (void) GstCaps * gst_static_caps_get (GstStaticCaps * static_caps) { - GstCaps *caps; + GstCaps **caps; g_return_val_if_fail (static_caps != NULL, NULL); - caps = (GstCaps *) static_caps; + caps = &static_caps->caps; /* refcount is 0 when we need to convert */ - if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) == 0)) { + if (G_UNLIKELY (*caps == NULL)) { const char *string; - GstCaps temp; G_LOCK (static_caps_lock); /* check if other thread already updated */ - if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) > 0)) + if (G_UNLIKELY (*caps != NULL)) goto done; string = static_caps->string; @@ -393,28 +391,21 @@ gst_static_caps_get (GstStaticCaps * static_caps) GST_CAT_TRACE (GST_CAT_CAPS, "creating %p", static_caps); - /* we construct the caps on the stack, then copy over the struct into our - * real caps, refcount last. We do this because we must leave the refcount - * of the result caps to 0 so that other threads don't run away with the - * caps while we are constructing it. */ - gst_caps_init (&temp, sizeof (GstCaps)); + *caps = gst_caps_from_string (string); /* convert to string */ - if (G_UNLIKELY (!gst_caps_from_string_inplace (&temp, string))) + if (G_UNLIKELY (*caps == NULL)) g_critical ("Could not convert static caps \"%s\"", string); - GST_MINI_OBJECT_REFCOUNT (&temp) = 0; - memcpy (caps, &temp, sizeof (GstCaps)); - gst_caps_ref (caps); - GST_CAT_TRACE (GST_CAT_CAPS, "created %p", static_caps); done: G_UNLOCK (static_caps_lock); } /* ref the caps, makes it not writable */ - gst_caps_ref (caps); + if (G_LIKELY (*caps != NULL)) + gst_caps_ref (*caps); - return caps; + return *caps; /* ERRORS */ no_string: @@ -427,30 +418,16 @@ no_string: /** * gst_static_caps_cleanup: - * @static_caps: the #GstStaticCaps to convert + * @static_caps: the #GstStaticCaps to clean * - * Clean up the caps contained in @static_caps when the refcount is 0. + * Clean up the cached caps contained in @static_caps. */ void gst_static_caps_cleanup (GstStaticCaps * static_caps) { - GstCaps *caps = (GstCaps *) static_caps; - - /* FIXME: this is not threadsafe */ - if (GST_CAPS_REFCOUNT_VALUE (caps) == 1) { - GstStructure *structure; - guint i, clen; - - clen = GST_CAPS_LEN (caps); - - for (i = 0; i < clen; i++) { - structure = (GstStructure *) gst_caps_get_structure (caps, i); - gst_structure_set_parent_refcount (structure, NULL); - gst_structure_free (structure); - } - g_ptr_array_free (GST_CAPS_ARRAY (caps), TRUE); - GST_CAPS_REFCOUNT (caps) = 0; - } + G_LOCK (static_caps_lock); + gst_caps_replace (&static_caps->caps, NULL); + G_UNLOCK (static_caps_lock); } /* manipulation */ diff --git a/gst/gstcaps.h b/gst/gstcaps.h index 320471662e..4b59c4876c 100644 --- a/gst/gstcaps.h +++ b/gst/gstcaps.h @@ -129,8 +129,7 @@ typedef enum { */ #define GST_STATIC_CAPS(string) \ { \ - /* miniobject */ { { 0, 0, 0, 0, NULL, NULL, NULL, 0, NULL }, \ - /* caps */ NULL }, \ + /* caps */ NULL, \ /* string */ string, \ GST_PADDING_INIT \ } @@ -361,7 +360,7 @@ struct _GstCaps { */ struct _GstStaticCaps { /*< public >*/ - GstCaps caps; + GstCaps *caps; const char *string; /*< private >*/ diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index e18d0f3898..1cf90397df 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -253,7 +253,7 @@ gst_element_register (GstPlugin * plugin, const gchar * name, guint rank, newt->name_template = g_intern_string (templ->name_template); newt->direction = templ->direction; newt->presence = templ->presence; - newt->static_caps.caps.mini_object.refcount = 0; + newt->static_caps.caps = NULL; newt->static_caps.string = g_intern_string (caps_string); factory->staticpadtemplates = g_list_append (factory->staticpadtemplates, newt); diff --git a/gst/gstregistrychunks.c b/gst/gstregistrychunks.c index d2900b74fb..29feddc46d 100644 --- a/gst/gstregistrychunks.c +++ b/gst/gstregistrychunks.c @@ -493,7 +493,7 @@ gst_registry_chunks_load_pad_template (GstElementFactory * factory, gchar ** in, template = g_slice_new (GstStaticPadTemplate); template->presence = pt->presence; template->direction = (GstPadDirection) pt->direction; - template->static_caps.caps.mini_object.refcount = 0; + template->static_caps.caps = NULL; /* unpack pad template strings */ unpack_const_string (*in, template->name_template, end, fail);