+
+/**
+ * g_param_get_default_value:
+ * @param: a #GParamSpec
+ *
+ * Gets the default value of @param as a pointer to a #GValue.
+ *
+ * The #GValue will remain value for the life of @param.
+ *
+ * Returns: a pointer to a #GValue which must not be modified
+ *
+ * Since: 2.38
+ **/
+const GValue *
+g_param_spec_get_default_value (GParamSpec *pspec)
+{
+ GParamSpecPrivate *priv = g_param_spec_get_private (pspec);
+
+ /* We use the type field of the GValue as the key for the once because
+ * it will be zero before it is initialised and non-zero after. We
+ * have to take care that we don't write a non-zero value to the type
+ * field before we are completely done, however, because then another
+ * thread could come along and find the value partially-initialised.
+ *
+ * In order to accomplish this we store the default value in a
+ * stack-allocated GValue. We then set the type field in that value
+ * to zero and copy the contents into place. We then end by storing
+ * the type as the last step in order to ensure that we're completely
+ * done before a g_once_init_enter() could take the fast path in
+ * another thread.
+ */
+ if (g_once_init_enter (&priv->default_value.g_type))
+ {
+ GValue default_value = G_VALUE_INIT;
+
+ g_value_init (&default_value, pspec->value_type);
+ g_param_value_set_default (pspec, &default_value);
+
+ /* store all but the type */
+ default_value.g_type = 0;
+ priv->default_value = default_value;
+
+ g_once_init_leave (&priv->default_value.g_type, pspec->value_type);
+ }
+
+ return &priv->default_value;
+}