g_object_unref (object);
}
+static void
+consider_issuing_property_deprecation_warning (const GParamSpec *pspec)
+{
+ static GHashTable *already_warned_table;
+ static const gchar *enable_diagnostic;
+ static GMutex already_warned_lock;
+ gboolean already;
+
+ if (!(pspec->flags & G_PARAM_DEPRECATED))
+ return;
+
+ if (g_once_init_enter (&enable_diagnostic))
+ {
+ const gchar *value = g_getenv ("G_ENABLE_DIAGNOSTIC");
+
+ if (!value)
+ value = "-";
+
+ g_once_init_leave (&enable_diagnostic, value);
+ }
+
+ if (enable_diagnostic[0] == '0')
+ return;
+
+ /* We hash only on property names: this means that we could end up in
+ * a situation where we fail to emit a warning about a pair of
+ * same-named deprecated properties used on two separate types.
+ * That's pretty unlikely to occur, and even if it does, you'll still
+ * have seen the warning for the first one...
+ *
+ * Doing it this way lets us hash directly on the (interned) property
+ * name pointers.
+ */
+ g_mutex_lock (&already_warned_lock);
+
+ if (already_warned_table == NULL)
+ already_warned_table = g_hash_table_new (NULL, NULL);
+
+ already = g_hash_table_contains (already_warned_table, (gpointer) pspec->name);
+ if (!already)
+ g_hash_table_add (already_warned_table, (gpointer) pspec->name);
+
+ g_mutex_unlock (&already_warned_lock);
+
+ if (!already)
+ g_warning ("The property %s:%s is deprecated and shouldn't be used "
+ "anymore. It will be removed in a future version.",
+ g_type_name (pspec->owner_type), pspec->name);
+}
+
static inline void
object_get_property (GObject *object,
GParamSpec *pspec,
redirect = g_param_spec_get_redirect_target (pspec);
if (redirect)
- pspec = redirect;
-
+ pspec = redirect;
+
+ consider_issuing_property_deprecation_warning (pspec);
+
class->get_property (object, param_id, value, pspec);
}
GObjectClass *class = g_type_class_peek (pspec->owner_type);
guint param_id = PARAM_SPEC_PARAM_ID (pspec);
GParamSpec *redirect;
- static const gchar * enable_diagnostic = NULL;
if (class == NULL)
{
if (redirect)
pspec = redirect;
- if (G_UNLIKELY (!enable_diagnostic))
- {
- enable_diagnostic = g_getenv ("G_ENABLE_DIAGNOSTIC");
- if (!enable_diagnostic)
- enable_diagnostic = "0";
- }
-
- if (enable_diagnostic[0] == '1')
- {
- if (pspec->flags & G_PARAM_DEPRECATED)
- {
- /* don't warn for automatically provided construct properties */
- if (!(pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) ||
- !object_in_construction (object))
- {
- g_warning ("The property %s:%s is deprecated and shouldn't be used "
- "anymore. It will be removed in a future version.",
- G_OBJECT_TYPE_NAME (object), pspec->name);
- }
- }
- }
-
/* provide a copy to work from, convert (if necessary) and validate */
g_value_init (&tmp_value, pspec->value_type);
if (!g_value_transform (value, &tmp_value))
for (j = 0; j < n_params; j++)
if (params[j].pspec == pspec)
{
+ consider_issuing_property_deprecation_warning (pspec);
value = params[j].value;
break;
}
/* set remaining properties */
for (i = 0; i < n_params; i++)
if (!(params[i].pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
- object_set_property (object, params[i].pspec, params[i].value, nqueue);
+ {
+ consider_issuing_property_deprecation_warning (params[i].pspec);
+ object_set_property (object, params[i].pspec, params[i].value, nqueue);
+ }
/* If nqueue is non-NULL then we are frozen. Thaw it. */
if (nqueue)
for (j = 0; j < n_params; j++)
if (params[j].pspec == pspec)
{
+ consider_issuing_property_deprecation_warning (pspec);
value = params[j].value;
break;
}
*/
for (i = 0; i < n_params; i++)
if (!(params[i].pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
- object_set_property (object, params[i].pspec, params[i].value, nqueue);
+ {
+ consider_issuing_property_deprecation_warning (params[i].pspec);
+ object_set_property (object, params[i].pspec, params[i].value, nqueue);
+ }
g_object_notify_queue_thaw (object, nqueue);
}
g_value_unset (&value);
break;
}
-
+
+ consider_issuing_property_deprecation_warning (pspec);
object_set_property (object, pspec, &value, nqueue);
g_value_unset (&value);
-
+
name = va_arg (var_args, gchar*);
}
g_warning ("%s: construct property \"%s\" for object '%s' can't be set after construction",
G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object));
else
- object_set_property (object, pspec, value, nqueue);
-
+ {
+ consider_issuing_property_deprecation_warning (pspec);
+ object_set_property (object, pspec, value, nqueue);
+ }
+
g_object_notify_queue_thaw (object, nqueue);
g_object_unref (object);
}
* Otherwise, the reference count of the object is decreased and the
* pointer is set to %NULL.
*
- * This function is threadsafe and modifies the pointer atomically,
- * using memory barriers where needed.
- *
* A macro is also included that allows this function to be used without
* pointer casts.
*
* or may not include using @old_destroy as sometimes replacement
* should not destroy the object in the normal way.
*
- * Return: %TRUE if the existing value for @quark was replaced
+ * Returns: %TRUE if the existing value for @quark was replaced
* by @newval, %FALSE otherwise.
*
* Since: 2.34
* or may not include using @old_destroy as sometimes replacement
* should not destroy the object in the normal way.
*
- * Return: %TRUE if the existing value for @key was replaced
+ * Returns: %TRUE if the existing value for @key was replaced
* by @newval, %FALSE otherwise.
*
* Since: 2.34