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.
This commit is contained in:
Matthias Clasen 2022-08-27 21:34:58 -04:00 committed by Philip Withnall
parent 794ee60306
commit 99c7d60869
3 changed files with 50 additions and 7 deletions

View File

@ -4562,6 +4562,7 @@ g_task_set_check_cancellable
g_task_set_return_on_cancel g_task_set_return_on_cancel
g_task_set_source_tag g_task_set_source_tag
g_task_set_name g_task_set_name
g_task_set_static_name
<SUBSECTION> <SUBSECTION>
g_task_report_error g_task_report_error
g_task_report_new_error g_task_report_new_error

View File

@ -588,6 +588,7 @@ struct _GTask {
guint check_cancellable : 1; guint check_cancellable : 1;
guint synchronous : 1; guint synchronous : 1;
guint blocking_other_task : 1; guint blocking_other_task : 1;
guint name_is_static : 1;
GError *error; GError *error;
union { union {
@ -660,7 +661,8 @@ g_task_finalize (GObject *object)
g_clear_object (&task->source_object); g_clear_object (&task->source_object);
g_clear_object (&task->cancellable); g_clear_object (&task->cancellable);
g_free (task->name); if (!task->name_is_static)
g_free (task->name);
if (task->context) if (task->context)
g_main_context_unref (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); task = g_task_new (source_object, NULL, callback, callback_data);
g_task_set_source_tag (task, source_tag); 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_task_return_error (task, error);
g_object_unref (task); g_object_unref (task);
} }
@ -1028,16 +1030,41 @@ void
* Since: 2.60 * Since: 2.60
*/ */
void void
g_task_set_name (GTask *task, (g_task_set_name) (GTask *task,
const gchar *name) const char *name)
{ {
gchar *new_name; char *new_name;
g_return_if_fail (G_IS_TASK (task)); g_return_if_fail (G_IS_TASK (task));
new_name = g_strdup (name); 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 = 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 @tasks 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;
} }
/** /**

View File

@ -79,6 +79,9 @@ void g_task_set_source_tag (GTask *task,
GIO_AVAILABLE_IN_2_60 GIO_AVAILABLE_IN_2_60
void g_task_set_name (GTask *task, void g_task_set_name (GTask *task,
const gchar *name); 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. */ /* Macro wrapper to set the task name when setting the source tag. */
#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_60 #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_60
@ -86,10 +89,22 @@ void g_task_set_name (GTask *task,
GTask *_task = (task); \ GTask *_task = (task); \
(g_task_set_source_tag) (_task, tag); \ (g_task_set_source_tag) (_task, tag); \
if (g_task_get_name (_task) == NULL) \ 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 } G_STMT_END
#endif #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 GIO_AVAILABLE_IN_2_36
gpointer g_task_get_source_object (GTask *task); gpointer g_task_get_source_object (GTask *task);
GIO_AVAILABLE_IN_2_36 GIO_AVAILABLE_IN_2_36