[glib/cheaper-source-names] mainloop: Add g_source_set_static_name
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/cheaper-source-names] mainloop: Add g_source_set_static_name
- Date: Sat, 24 Jul 2021 12:39:54 +0000 (UTC)
commit 067a2a8fc84954ab4da5753d6b488e5a62d36be4
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Jul 24 08:38:11 2021 -0400
mainloop: Add g_source_set_static_name
g_source_set_name duplicates the string, and this is
showing up as one of the more prominent sources of strdups
in GTK profiles, despite all the names we use being literals.
Add a variant that avoids the overhead.
glib/gmain.c | 81 +++++++++++++++++++++++++++++++++++++--------------
glib/gmain.h | 3 ++
glib/tests/mainloop.c | 3 ++
3 files changed, 65 insertions(+), 22 deletions(-)
---
diff --git a/glib/gmain.c b/glib/gmain.c
index 4efa9ad6f..f36da1eea 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -364,6 +364,8 @@ struct _GSourcePrivate
GSList *fds;
GSourceDisposeFunc dispose;
+
+ gboolean static_name;
};
typedef struct _GSourceIter
@@ -2059,6 +2061,41 @@ g_source_get_can_recurse (GSource *source)
return (source->flags & G_SOURCE_CAN_RECURSE) != 0;
}
+static void
+g_source_set_name_full (GSource *source,
+ const char *name,
+ gboolean is_static)
+{
+ GMainContext *context;
+
+ g_return_if_fail (source != NULL);
+ g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
+
+ context = source->context;
+
+ if (context)
+ LOCK_CONTEXT (context);
+
+ TRACE (GLIB_SOURCE_SET_NAME (source, name));
+
+ /* setting back to NULL is allowed, just because it's
+ * weird if get_name can return NULL but you can't
+ * set that.
+ */
+
+ if (!source->priv->static_name)
+ g_free (source->name);
+
+ if (is_static)
+ source->name = (char *)name;
+ else
+ source->name = g_strdup (name);
+
+ source->priv->static_name = is_static;
+
+ if (context)
+ UNLOCK_CONTEXT (context);
+}
/**
* g_source_set_name:
@@ -2082,34 +2119,33 @@ g_source_get_can_recurse (GSource *source)
* the value, and changing the value will free it while the other thread
* may be attempting to use it.
*
+ * Also see g_source_set_static_name().
+ *
* Since: 2.26
**/
void
g_source_set_name (GSource *source,
const char *name)
{
- GMainContext *context;
-
- g_return_if_fail (source != NULL);
- g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
-
- context = source->context;
-
- if (context)
- LOCK_CONTEXT (context);
-
- TRACE (GLIB_SOURCE_SET_NAME (source, name));
-
- /* setting back to NULL is allowed, just because it's
- * weird if get_name can return NULL but you can't
- * set that.
- */
-
- g_free (source->name);
- source->name = g_strdup (name);
+ g_source_set_name_full (source, name, FALSE);
+}
- if (context)
- UNLOCK_CONTEXT (context);
+/**
+ * g_source_set_static_name:
+ * @source: a #GSource
+ * @name: debug name for the source
+ *
+ * A variant of g_source_set_name() that does not
+ * duplicate the @name, and can only be used with
+ * string literals.
+ *
+ * Since: 2.70
+ */
+void
+g_source_set_static_name (GSource *source,
+ const char *name)
+{
+ g_source_set_name_full (source, name, TRUE);
}
/**
@@ -2284,7 +2320,8 @@ g_source_unref_internal (GSource *source,
g_warn_if_fail (old_ref_count == 1);
}
- g_free (source->name);
+ if (!source->priv->static_name)
+ g_free (source->name);
source->name = NULL;
g_slist_free (source->poll_fds);
diff --git a/glib/gmain.h b/glib/gmain.h
index 8428e01a4..8e15f3da4 100644
--- a/glib/gmain.h
+++ b/glib/gmain.h
@@ -605,6 +605,9 @@ gboolean g_source_is_destroyed (GSource *source);
GLIB_AVAILABLE_IN_ALL
void g_source_set_name (GSource *source,
const char *name);
+GLIB_AVAILABLE_IN_2_70
+void g_source_set_static_name (GSource *source,
+ const char *name);
GLIB_AVAILABLE_IN_ALL
const char * g_source_get_name (GSource *source);
GLIB_AVAILABLE_IN_ALL
diff --git a/glib/tests/mainloop.c b/glib/tests/mainloop.c
index 77e21f548..4ef0e9c7d 100644
--- a/glib/tests/mainloop.c
+++ b/glib/tests/mainloop.c
@@ -83,6 +83,9 @@ test_maincontext_basic (void)
g_assert_true (g_source_get_can_recurse (source));
g_assert_cmpstr (g_source_get_name (source), ==, "d");
+ g_source_set_static_name (source, "still d");
+ g_assert_cmpstr (g_source_get_name (source), ==, "still d");
+
g_assert_null (g_main_context_find_source_by_user_data (ctx, NULL));
g_assert_null (g_main_context_find_source_by_funcs_user_data (ctx, &funcs, NULL));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]