summaryrefslogtreecommitdiff
path: root/gio
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-08-27 21:34:58 -0400
committerPhilip Withnall <pwithnall@endlessos.org>2022-11-01 11:48:38 +0000
commit99c7d6086922a53b0ce8aa90e5d147872724eafb (patch)
tree5143c58ae8455d4c0f8fe9b7d63c13a7c2afe12e /gio
parent794ee6030688b9bc6e7ca0624281622c50f9094e (diff)
downloadglib-99c7d6086922a53b0ce8aa90e5d147872724eafb.tar.gz
gtask: Add g_task_set_static_name()
Similar to g_source_set_static_name, this avoids strdup overhead for debug-only information in possibly hot code paths. We also add a macro wrapper for g_task_set_name that uses __builtin_constant_p to decide whether to use g_task_set_name or g_task_set_static_name.
Diffstat (limited to 'gio')
-rw-r--r--gio/gtask.c39
-rw-r--r--gio/gtask.h17
2 files changed, 49 insertions, 7 deletions
diff --git a/gio/gtask.c b/gio/gtask.c
index 5464a1cb0..1d5b37e85 100644
--- a/gio/gtask.c
+++ b/gio/gtask.c
@@ -588,6 +588,7 @@ struct _GTask {
guint check_cancellable : 1;
guint synchronous : 1;
guint blocking_other_task : 1;
+ guint name_is_static : 1;
GError *error;
union {
@@ -660,7 +661,8 @@ g_task_finalize (GObject *object)
g_clear_object (&task->source_object);
g_clear_object (&task->cancellable);
- g_free (task->name);
+ if (!task->name_is_static)
+ g_free (task->name);
if (task->context)
g_main_context_unref (task->context);
@@ -769,7 +771,7 @@ g_task_report_error (gpointer source_object,
task = g_task_new (source_object, NULL, callback, callback_data);
g_task_set_source_tag (task, source_tag);
- g_task_set_name (task, G_STRFUNC);
+ g_task_set_static_name (task, G_STRFUNC);
g_task_return_error (task, error);
g_object_unref (task);
}
@@ -1028,16 +1030,41 @@ void
* Since: 2.60
*/
void
-g_task_set_name (GTask *task,
- const gchar *name)
+(g_task_set_name) (GTask *task,
+ const char *name)
{
- gchar *new_name;
+ char *new_name;
g_return_if_fail (G_IS_TASK (task));
new_name = g_strdup (name);
- g_free (task->name);
+ if (!task->name_is_static)
+ g_free (task->name);
task->name = g_steal_pointer (&new_name);
+ task->name_is_static = FALSE;
+}
+
+/**
+ * g_task_set_static_name:
+ * @task: a #GTask
+ * @name: (nullable): a human readable name for the task. Must be a string literal
+ *
+ * Sets @task’s name, used in debugging and profiling.
+ *
+ * This is a variant of g_task_set_name() that avoids copying @name.
+ *
+ * Since: 2.76
+ */
+void
+g_task_set_static_name (GTask *task,
+ const char *name)
+{
+ g_return_if_fail (G_IS_TASK (task));
+
+ if (!task->name_is_static)
+ g_free (task->name);
+ task->name = (char *) name;
+ task->name_is_static = TRUE;
}
/**
diff --git a/gio/gtask.h b/gio/gtask.h
index 0f17ad53f..368d60ff2 100644
--- a/gio/gtask.h
+++ b/gio/gtask.h
@@ -79,6 +79,9 @@ void g_task_set_source_tag (GTask *task,
GIO_AVAILABLE_IN_2_60
void g_task_set_name (GTask *task,
const gchar *name);
+GIO_AVAILABLE_IN_2_76
+void g_task_set_static_name (GTask *task,
+ const gchar *name);
/* Macro wrapper to set the task name when setting the source tag. */
#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_60
@@ -86,9 +89,21 @@ void g_task_set_name (GTask *task,
GTask *_task = (task); \
(g_task_set_source_tag) (_task, tag); \
if (g_task_get_name (_task) == NULL) \
- g_task_set_name (_task, G_STRINGIFY (tag)); \
+ g_task_set_static_name (_task, G_STRINGIFY (tag)); \
+} G_STMT_END
+#endif
+
+#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_76
+#if defined (__GNUC__) && (__GNUC__ >= 2)
+#define g_task_set_name(task, name) G_STMT_START { \
+ GTask *_task = (task); \
+ if (__builtin_constant_p (name)) \
+ g_task_set_static_name (_task, name); \
+ else \
+ g_task_set_name (_task, name); \
} G_STMT_END
#endif
+#endif
GIO_AVAILABLE_IN_2_36
gpointer g_task_get_source_object (GTask *task);