autoconvert: factories don't need the lock

An atomic is enough, they can only be set once.
This commit is contained in:
Olivier Crête 2014-05-07 20:08:08 -04:00
parent c47c26bf1f
commit 1660538615
2 changed files with 26 additions and 33 deletions

View file

@ -211,14 +211,19 @@ gst_auto_convert_dispose (GObject * object)
{ {
GstAutoConvert *autoconvert = GST_AUTO_CONVERT (object); GstAutoConvert *autoconvert = GST_AUTO_CONVERT (object);
GST_AUTOCONVERT_LOCK (autoconvert);
g_clear_object (&autoconvert->current_subelement); g_clear_object (&autoconvert->current_subelement);
g_clear_object (&autoconvert->current_internal_sinkpad); g_clear_object (&autoconvert->current_internal_sinkpad);
g_clear_object (&autoconvert->current_internal_srcpad); g_clear_object (&autoconvert->current_internal_srcpad);
gst_plugin_feature_list_free (autoconvert->factories); for (;;) {
autoconvert->factories = NULL; GList *factories = g_atomic_pointer_get (&autoconvert->factories);
GST_AUTOCONVERT_UNLOCK (autoconvert);
if (g_atomic_pointer_compare_and_exchange (&autoconvert->factories,
factories, NULL)) {
gst_plugin_feature_list_free (factories);
break;
}
}
G_OBJECT_CLASS (gst_auto_convert_parent_class)->dispose (object); G_OBJECT_CLASS (gst_auto_convert_parent_class)->dispose (object);
} }
@ -234,15 +239,18 @@ gst_auto_convert_set_property (GObject * object,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
case PROP_FACTORIES: case PROP_FACTORIES:
GST_AUTOCONVERT_LOCK (autoconvert); if (g_atomic_pointer_get (&autoconvert->factories) == NULL) {
if (autoconvert->factories == NULL) {
GList *factories = g_value_get_pointer (value); GList *factories = g_value_get_pointer (value);
autoconvert->factories = g_list_copy (factories); factories = g_list_copy (factories);
g_list_foreach (autoconvert->factories, (GFunc) g_object_ref, NULL); if (g_atomic_pointer_compare_and_exchange (&autoconvert->factories,
} else NULL, factories))
g_list_foreach (factories, (GFunc) g_object_ref, NULL);
else
g_list_free (factories);
} else {
GST_WARNING_OBJECT (object, "Can not reset factories after they" GST_WARNING_OBJECT (object, "Can not reset factories after they"
" have been set or auto-discovered"); " have been set or auto-discovered");
GST_AUTOCONVERT_UNLOCK (autoconvert); }
break; break;
} }
} }
@ -258,9 +266,8 @@ gst_auto_convert_get_property (GObject * object,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
case PROP_FACTORIES: case PROP_FACTORIES:
GST_AUTOCONVERT_LOCK (autoconvert); g_value_set_pointer (value,
g_value_set_pointer (value, autoconvert->factories); g_atomic_pointer_get (&autoconvert->factories));
GST_AUTOCONVERT_UNLOCK (autoconvert);
break; break;
} }
} }
@ -735,9 +742,7 @@ gst_auto_convert_sink_setcaps (GstAutoConvert * autoconvert, GstCaps * caps)
other_caps = gst_pad_peer_query_caps (autoconvert->srcpad, NULL); other_caps = gst_pad_peer_query_caps (autoconvert->srcpad, NULL);
GST_AUTOCONVERT_LOCK (autoconvert); factories = g_atomic_pointer_get (&autoconvert->factories);
factories = autoconvert->factories;
GST_AUTOCONVERT_UNLOCK (autoconvert);
if (!factories) if (!factories)
factories = gst_auto_convert_load_factories (autoconvert); factories = gst_auto_convert_load_factories (autoconvert);
@ -874,7 +879,6 @@ static GList *
gst_auto_convert_load_factories (GstAutoConvert * autoconvert) gst_auto_convert_load_factories (GstAutoConvert * autoconvert)
{ {
GList *all_factories; GList *all_factories;
GList *out_factories;
all_factories = all_factories =
gst_registry_feature_filter (gst_registry_get (), gst_registry_feature_filter (gst_registry_get (),
@ -884,20 +888,12 @@ gst_auto_convert_load_factories (GstAutoConvert * autoconvert)
g_assert (all_factories); g_assert (all_factories);
GST_AUTOCONVERT_LOCK (autoconvert); if (g_atomic_pointer_compare_and_exchange (&autoconvert->factories, NULL,
if (autoconvert->factories == NULL) { all_factories)) {
autoconvert->factories = all_factories;
all_factories = NULL;
}
out_factories = autoconvert->factories;
GST_AUTOCONVERT_UNLOCK (autoconvert);
if (all_factories) {
/* In this case, someone set the property while we were looking! */
gst_plugin_feature_list_free (all_factories); gst_plugin_feature_list_free (all_factories);
} }
return out_factories; return g_atomic_pointer_get (&autoconvert->factories);
} }
/* In this case, we should almost always have an internal element, because /* In this case, we should almost always have an internal element, because
@ -1057,9 +1053,7 @@ gst_auto_convert_getcaps (GstAutoConvert * autoconvert, GstCaps * filter,
goto out; goto out;
} }
GST_AUTOCONVERT_LOCK (autoconvert); factories = g_atomic_pointer_get (&autoconvert->factories);
factories = autoconvert->factories;
GST_AUTOCONVERT_UNLOCK (autoconvert);
if (!factories) if (!factories)
factories = gst_auto_convert_load_factories (autoconvert); factories = gst_auto_convert_load_factories (autoconvert);

View file

@ -41,8 +41,7 @@ struct _GstAutoConvert
/*< private >*/ /*< private >*/
GstBin bin; /* we extend GstBin */ GstBin bin; /* we extend GstBin */
/* Protected by the object lock too */ volatile GList *factories;
GList *factories;
GstPad *sinkpad; GstPad *sinkpad;
GstPad *srcpad; GstPad *srcpad;