[glib/resources-extraneous-symbol: 1/2] Add g_object_notify_by_pspecs
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/resources-extraneous-symbol: 1/2] Add g_object_notify_by_pspecs
- Date: Thu, 12 May 2022 03:09:45 +0000 (UTC)
commit 020597920458d0b23066b6477e90051e06f1f266
Author: Matthias Clasen <mclasen redhat com>
Date: Fri May 6 16:17:45 2022 -0400
Add g_object_notify_by_pspecs
This is an attempt to reduce the overhead of looking
up the notify queue for each property.
gobject/gobject.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++--------
gobject/gobject.h | 4 +++
2 files changed, 73 insertions(+), 11 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index d33d8e5b04..81911f9142 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -368,6 +368,28 @@ g_object_notify_queue_add (GObject *object,
G_UNLOCK(notify_lock);
}
+static inline void
+g_object_notify_queue_add_many (GObject *object,
+ GObjectNotifyQueue *nqueue,
+ GParamSpec **pspec,
+ guint n)
+{
+ G_LOCK(notify_lock);
+
+ g_assert (nqueue->n_pspecs + n < 65535);
+
+ for (int i = 0; i < n; i++)
+ {
+ if (g_slist_find (nqueue->pspecs, pspec[i]) == NULL)
+ {
+ nqueue->pspecs = g_slist_prepend (nqueue->pspecs, pspec[i]);
+ nqueue->n_pspecs++;
+ }
+ }
+
+ G_UNLOCK(notify_lock);
+}
+
#ifdef G_ENABLE_DEBUG
G_LOCK_DEFINE_STATIC (debug_objects);
static guint debug_objects_count = 0;
@@ -1297,7 +1319,7 @@ g_object_freeze_notify (GObject *object)
g_object_unref (object);
}
-static GParamSpec *
+static inline GParamSpec *
get_notify_pspec (GParamSpec *pspec)
{
GParamSpec *redirected;
@@ -1316,14 +1338,23 @@ get_notify_pspec (GParamSpec *pspec)
}
static inline void
-g_object_notify_by_spec_internal (GObject *object,
- GParamSpec *pspec)
+g_object_notify_by_spec_internal (GObject *object,
+ GParamSpec **pspecs,
+ guint n_pspec)
{
- GParamSpec *notify_pspec;
+ GParamSpec **notify_pspecs;
+ guint n = 0;
- notify_pspec = get_notify_pspec (pspec);
+ notify_pspecs = g_alloca (sizeof (GParamSpec *) * n_pspec);
- if (notify_pspec != NULL)
+ for (int i = 0; i < n_pspec; i++)
+ {
+ notify_pspecs[n] = get_notify_pspec (pspecs[i]);
+ if (notify_pspecs[n])
+ n++;
+ }
+
+ if (n > 0)
{
GObjectNotifyQueue *nqueue;
@@ -1333,13 +1364,13 @@ g_object_notify_by_spec_internal (GObject *object,
if (nqueue != NULL)
{
/* we're frozen, so add to the queue and release our freeze */
- g_object_notify_queue_add (object, nqueue, notify_pspec);
+ g_object_notify_queue_add_many (object, nqueue, notify_pspecs, n);
g_object_notify_queue_thaw (object, nqueue);
}
else
/* not frozen, so just dispatch the notification directly */
G_OBJECT_GET_CLASS (object)
- ->dispatch_properties_changed (object, 1, ¬ify_pspec);
+ ->dispatch_properties_changed (object, n, notify_pspecs);
}
}
@@ -1386,7 +1417,7 @@ g_object_notify (GObject *object,
G_OBJECT_TYPE_NAME (object),
property_name);
else
- g_object_notify_by_spec_internal (object, pspec);
+ g_object_notify_by_spec_internal (object, &pspec, 1);
g_object_unref (object);
}
@@ -1440,7 +1471,6 @@ void
g_object_notify_by_pspec (GObject *object,
GParamSpec *pspec)
{
-
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
@@ -1448,7 +1478,35 @@ g_object_notify_by_pspec (GObject *object,
return;
g_object_ref (object);
- g_object_notify_by_spec_internal (object, pspec);
+ g_object_notify_by_spec_internal (object, &pspec, 1);
+ g_object_unref (object);
+}
+
+/**
+ * g_object_notify_by_pspecs:
+ * @object: a #GObject
+ * @pspecs: (array, length=n_pspecs): array of #GParamSpecs of properties installed on the class of @object
+ * @n_pspecs: length of @pspecs
+ *
+ * Emits a "notify" signal for the properties specified by @pspecs on @object.
+ *
+ * This function omits the property name lookup, hence it is faster than
+ * g_object_notify().
+ *
+ * Since: REPLACEME
+ */
+void
+g_object_notify_by_pspecs (GObject *object,
+ GParamSpec **pspecs,
+ guint n_pspecs)
+{
+ g_return_if_fail (G_IS_OBJECT (object));
+
+ if (g_atomic_int_get (&object->ref_count) == 0)
+ return;
+
+ g_object_ref (object);
+ g_object_notify_by_spec_internal (object, pspecs, n_pspecs);
g_object_unref (object);
}
diff --git a/gobject/gobject.h b/gobject/gobject.h
index 3dc4f7f480..be3884444b 100644
--- a/gobject/gobject.h
+++ b/gobject/gobject.h
@@ -510,6 +510,10 @@ GLIB_AVAILABLE_IN_ALL
void g_object_notify_by_pspec (GObject *object,
GParamSpec *pspec);
GLIB_AVAILABLE_IN_ALL
+void g_object_notify_by_pspecs (GObject *object,
+ GParamSpec **pspecs,
+ guint n_pspecs);
+GLIB_AVAILABLE_IN_ALL
void g_object_thaw_notify (GObject *object);
GLIB_AVAILABLE_IN_ALL
gboolean g_object_is_floating (gpointer object);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]