[glib: 3/4] gmain: Refactor idle-once and timeout-once to avoid a closure allocation
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 3/4] gmain: Refactor idle-once and timeout-once to avoid a closure allocation
- Date: Fri, 27 May 2022 12:51:16 +0000 (UTC)
commit 6db112f9a7f5ef353a46857d9f4608ae99579541
Author: Philip Withnall <pwithnall endlessos org>
Date: Fri May 27 13:23:21 2022 +0100
gmain: Refactor idle-once and timeout-once to avoid a closure allocation
Instead store a bit inside `GTimeoutSource` and `GIdleSource` to
indicate that they are one-shot sources, and that their callbacks have a
different type and should always be assumed to return `G_SOURCE_REMOVE`.
This should make one-shot idle and timeout sources a teeny weeny little
bit cheaper to set up.
From a suggestion here: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2684#note_1462917
Signed-off-by: Philip Withnall <pwithnall endlessos org>
glib/gmain.c | 94 ++++++++++++++++++++++++++----------------------------------
1 file changed, 40 insertions(+), 54 deletions(-)
---
diff --git a/glib/gmain.c b/glib/gmain.c
index ecff188bf0..a0ade8acbb 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -336,6 +336,7 @@ struct _GMainLoop
struct _GIdleSource
{
GSource source;
+ gboolean one_shot;
};
struct _GTimeoutSource
@@ -344,6 +345,7 @@ struct _GTimeoutSource
/* Measured in seconds if 'seconds' is TRUE, or milliseconds otherwise. */
guint interval;
gboolean seconds;
+ gboolean one_shot;
};
struct _GChildWatchSource
@@ -4976,7 +4978,16 @@ g_timeout_dispatch (GSource *source,
return FALSE;
}
- again = callback (user_data);
+ if (timeout_source->one_shot)
+ {
+ GSourceOnceFunc once_callback = (GSourceOnceFunc) callback;
+ once_callback (user_data);
+ again = G_SOURCE_REMOVE;
+ }
+ else
+ {
+ again = callback (user_data);
+ }
TRACE (GLIB_TIMEOUT_DISPATCH (source, source->context, callback, user_data, again));
@@ -4988,13 +4999,15 @@ g_timeout_dispatch (GSource *source,
static GSource *
timeout_source_new (guint interval,
- gboolean seconds)
+ gboolean seconds,
+ gboolean one_shot)
{
GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
timeout_source->interval = interval;
timeout_source->seconds = seconds;
+ timeout_source->one_shot = one_shot;
g_timeout_set_expiration (timeout_source, g_get_monotonic_time ());
@@ -5019,7 +5032,7 @@ timeout_source_new (guint interval,
GSource *
g_timeout_source_new (guint interval)
{
- return timeout_source_new (interval, FALSE);
+ return timeout_source_new (interval, FALSE, FALSE);
}
/**
@@ -5045,13 +5058,14 @@ g_timeout_source_new (guint interval)
GSource *
g_timeout_source_new_seconds (guint interval)
{
- return timeout_source_new (interval, TRUE);
+ return timeout_source_new (interval, TRUE, FALSE);
}
static guint
timeout_add_full (gint priority,
guint interval,
gboolean seconds,
+ gboolean one_shot,
GSourceFunc function,
gpointer data,
GDestroyNotify notify)
@@ -5061,7 +5075,7 @@ timeout_add_full (gint priority,
g_return_val_if_fail (function != NULL, 0);
- source = timeout_source_new (interval, seconds);
+ source = timeout_source_new (interval, seconds, one_shot);
if (priority != G_PRIORITY_DEFAULT)
g_source_set_priority (source, priority);
@@ -5120,7 +5134,7 @@ g_timeout_add_full (gint priority,
gpointer data,
GDestroyNotify notify)
{
- return timeout_add_full (priority, interval, FALSE, function, data, notify);
+ return timeout_add_full (priority, interval, FALSE, FALSE, function, data, notify);
}
/**
@@ -5174,27 +5188,6 @@ g_timeout_add (guint32 interval,
interval, function, data, NULL);
}
-typedef struct {
- GSourceOnceFunc function;
- gpointer data;
-} OnceData;
-
-static void
-once_data_free (gpointer data)
-{
- g_free (data);
-}
-
-static gboolean
-once_function (gpointer data)
-{
- OnceData *once_data = data;
-
- once_data->function (once_data->data);
-
- return G_SOURCE_REMOVE;
-}
-
/**
* g_timeout_add_once:
* @interval: the time after which the function will be called, in
@@ -5219,19 +5212,7 @@ g_timeout_add_once (guint32 interval,
GSourceOnceFunc function,
gpointer data)
{
- OnceData *once_data;
-
- g_return_val_if_fail (function != NULL, 0);
-
- once_data = g_new (OnceData, 1);
- once_data->function = function;
- once_data->data = data;
-
- return g_timeout_add_full (G_PRIORITY_DEFAULT,
- interval,
- once_function,
- once_data,
- once_data_free);
+ return timeout_add_full (G_PRIORITY_DEFAULT, interval, FALSE, TRUE, (GSourceFunc) function, data, NULL);
}
/**
@@ -6002,6 +5983,7 @@ g_idle_dispatch (GSource *source,
GSourceFunc callback,
gpointer user_data)
{
+ GIdleSource *idle_source = (GIdleSource *)source;
gboolean again;
if (!callback)
@@ -6011,7 +5993,16 @@ g_idle_dispatch (GSource *source,
return FALSE;
}
- again = callback (user_data);
+ if (idle_source->one_shot)
+ {
+ GSourceOnceFunc once_callback = (GSourceOnceFunc) callback;
+ once_callback (user_data);
+ again = G_SOURCE_REMOVE;
+ }
+ else
+ {
+ again = callback (user_data);
+ }
TRACE (GLIB_IDLE_DISPATCH (source, source->context, callback, user_data, again));
@@ -6019,7 +6010,7 @@ g_idle_dispatch (GSource *source,
}
static GSource *
-idle_source_new (void)
+idle_source_new (gboolean one_shot)
{
GSource *source;
GIdleSource *idle_source;
@@ -6027,6 +6018,8 @@ idle_source_new (void)
source = g_source_new (&g_idle_funcs, sizeof (GIdleSource));
idle_source = (GIdleSource *) source;
+ idle_source->one_shot = one_shot;
+
g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE);
/* Set a default name on the source, just in case the caller does not. */
@@ -6051,11 +6044,12 @@ idle_source_new (void)
GSource *
g_idle_source_new (void)
{
- return idle_source_new ();
+ return idle_source_new (FALSE);
}
static guint
idle_add_full (gint priority,
+ gboolean one_shot,
GSourceFunc function,
gpointer data,
GDestroyNotify notify)
@@ -6065,7 +6059,7 @@ idle_add_full (gint priority,
g_return_val_if_fail (function != NULL, 0);
- source = idle_source_new ();
+ source = idle_source_new (one_shot);
if (priority != G_PRIORITY_DEFAULT_IDLE)
g_source_set_priority (source, priority);
@@ -6111,7 +6105,7 @@ g_idle_add_full (gint priority,
gpointer data,
GDestroyNotify notify)
{
- return idle_add_full (priority, function, data, notify);
+ return idle_add_full (priority, FALSE, function, data, notify);
}
/**
@@ -6165,15 +6159,7 @@ guint
g_idle_add_once (GSourceOnceFunc function,
gpointer data)
{
- OnceData *once_data;
-
- g_return_val_if_fail (function != NULL, 0);
-
- once_data = g_new (OnceData, 1);
- once_data->function = function;
- once_data->data = data;
-
- return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, once_function, once_data, once_data_free);
+ return idle_add_full (G_PRIORITY_DEFAULT_IDLE, TRUE, (GSourceFunc) function, data, NULL);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]