mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 11:12:11 +01:00
Merge branch 'source-once-no-allocs' into 'main'
gmain: Refactor idle-once and timeout-once to avoid a closure allocation See merge request GNOME/glib!2693
This commit is contained in:
commit
1c7966b58e
221
glib/gmain.c
221
glib/gmain.c
@ -235,6 +235,7 @@
|
|||||||
|
|
||||||
/* Types */
|
/* Types */
|
||||||
|
|
||||||
|
typedef struct _GIdleSource GIdleSource;
|
||||||
typedef struct _GTimeoutSource GTimeoutSource;
|
typedef struct _GTimeoutSource GTimeoutSource;
|
||||||
typedef struct _GChildWatchSource GChildWatchSource;
|
typedef struct _GChildWatchSource GChildWatchSource;
|
||||||
typedef struct _GUnixSignalWatchSource GUnixSignalWatchSource;
|
typedef struct _GUnixSignalWatchSource GUnixSignalWatchSource;
|
||||||
@ -332,12 +333,19 @@ struct _GMainLoop
|
|||||||
gint ref_count; /* (atomic) */
|
gint ref_count; /* (atomic) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _GIdleSource
|
||||||
|
{
|
||||||
|
GSource source;
|
||||||
|
gboolean one_shot;
|
||||||
|
};
|
||||||
|
|
||||||
struct _GTimeoutSource
|
struct _GTimeoutSource
|
||||||
{
|
{
|
||||||
GSource source;
|
GSource source;
|
||||||
/* Measured in seconds if 'seconds' is TRUE, or milliseconds otherwise. */
|
/* Measured in seconds if 'seconds' is TRUE, or milliseconds otherwise. */
|
||||||
guint interval;
|
guint interval;
|
||||||
gboolean seconds;
|
gboolean seconds;
|
||||||
|
gboolean one_shot;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GChildWatchSource
|
struct _GChildWatchSource
|
||||||
@ -4970,7 +4978,16 @@ g_timeout_dispatch (GSource *source,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timeout_source->one_shot)
|
||||||
|
{
|
||||||
|
GSourceOnceFunc once_callback = (GSourceOnceFunc) callback;
|
||||||
|
once_callback (user_data);
|
||||||
|
again = G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
again = callback (user_data);
|
again = callback (user_data);
|
||||||
|
}
|
||||||
|
|
||||||
TRACE (GLIB_TIMEOUT_DISPATCH (source, source->context, callback, user_data, again));
|
TRACE (GLIB_TIMEOUT_DISPATCH (source, source->context, callback, user_data, again));
|
||||||
|
|
||||||
@ -4980,6 +4997,23 @@ g_timeout_dispatch (GSource *source,
|
|||||||
return again;
|
return again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GSource *
|
||||||
|
timeout_source_new (guint interval,
|
||||||
|
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 ());
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_timeout_source_new:
|
* g_timeout_source_new:
|
||||||
* @interval: the timeout interval in milliseconds.
|
* @interval: the timeout interval in milliseconds.
|
||||||
@ -4998,13 +5032,7 @@ g_timeout_dispatch (GSource *source,
|
|||||||
GSource *
|
GSource *
|
||||||
g_timeout_source_new (guint interval)
|
g_timeout_source_new (guint interval)
|
||||||
{
|
{
|
||||||
GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
|
return timeout_source_new (interval, FALSE, FALSE);
|
||||||
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
|
||||||
|
|
||||||
timeout_source->interval = interval;
|
|
||||||
g_timeout_set_expiration (timeout_source, g_get_monotonic_time ());
|
|
||||||
|
|
||||||
return source;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5030,17 +5058,37 @@ g_timeout_source_new (guint interval)
|
|||||||
GSource *
|
GSource *
|
||||||
g_timeout_source_new_seconds (guint interval)
|
g_timeout_source_new_seconds (guint interval)
|
||||||
{
|
{
|
||||||
GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
|
return timeout_source_new (interval, TRUE, FALSE);
|
||||||
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
|
||||||
|
|
||||||
timeout_source->interval = interval;
|
|
||||||
timeout_source->seconds = TRUE;
|
|
||||||
|
|
||||||
g_timeout_set_expiration (timeout_source, g_get_monotonic_time ());
|
|
||||||
|
|
||||||
return source;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
timeout_add_full (gint priority,
|
||||||
|
guint interval,
|
||||||
|
gboolean seconds,
|
||||||
|
gboolean one_shot,
|
||||||
|
GSourceFunc function,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
GSource *source;
|
||||||
|
guint id;
|
||||||
|
|
||||||
|
g_return_val_if_fail (function != NULL, 0);
|
||||||
|
|
||||||
|
source = timeout_source_new (interval, seconds, one_shot);
|
||||||
|
|
||||||
|
if (priority != G_PRIORITY_DEFAULT)
|
||||||
|
g_source_set_priority (source, priority);
|
||||||
|
|
||||||
|
g_source_set_callback (source, function, data, notify);
|
||||||
|
id = g_source_attach (source, NULL);
|
||||||
|
|
||||||
|
TRACE (GLIB_TIMEOUT_ADD (source, g_main_context_default (), id, priority, interval, function, data));
|
||||||
|
|
||||||
|
g_source_unref (source);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_timeout_add_full: (rename-to g_timeout_add)
|
* g_timeout_add_full: (rename-to g_timeout_add)
|
||||||
@ -5086,24 +5134,7 @@ g_timeout_add_full (gint priority,
|
|||||||
gpointer data,
|
gpointer data,
|
||||||
GDestroyNotify notify)
|
GDestroyNotify notify)
|
||||||
{
|
{
|
||||||
GSource *source;
|
return timeout_add_full (priority, interval, FALSE, FALSE, function, data, notify);
|
||||||
guint id;
|
|
||||||
|
|
||||||
g_return_val_if_fail (function != NULL, 0);
|
|
||||||
|
|
||||||
source = g_timeout_source_new (interval);
|
|
||||||
|
|
||||||
if (priority != G_PRIORITY_DEFAULT)
|
|
||||||
g_source_set_priority (source, priority);
|
|
||||||
|
|
||||||
g_source_set_callback (source, function, data, notify);
|
|
||||||
id = g_source_attach (source, NULL);
|
|
||||||
|
|
||||||
TRACE (GLIB_TIMEOUT_ADD (source, g_main_context_default (), id, priority, interval, function, data));
|
|
||||||
|
|
||||||
g_source_unref (source);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5157,27 +5188,6 @@ g_timeout_add (guint32 interval,
|
|||||||
interval, function, data, NULL);
|
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:
|
* g_timeout_add_once:
|
||||||
* @interval: the time after which the function will be called, in
|
* @interval: the time after which the function will be called, in
|
||||||
@ -5202,19 +5212,7 @@ g_timeout_add_once (guint32 interval,
|
|||||||
GSourceOnceFunc function,
|
GSourceOnceFunc function,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
OnceData *once_data;
|
return timeout_add_full (G_PRIORITY_DEFAULT, interval, FALSE, TRUE, (GSourceFunc) function, data, NULL);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5985,6 +5983,7 @@ g_idle_dispatch (GSource *source,
|
|||||||
GSourceFunc callback,
|
GSourceFunc callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
GIdleSource *idle_source = (GIdleSource *)source;
|
||||||
gboolean again;
|
gboolean again;
|
||||||
|
|
||||||
if (!callback)
|
if (!callback)
|
||||||
@ -5994,13 +5993,41 @@ g_idle_dispatch (GSource *source,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (idle_source->one_shot)
|
||||||
|
{
|
||||||
|
GSourceOnceFunc once_callback = (GSourceOnceFunc) callback;
|
||||||
|
once_callback (user_data);
|
||||||
|
again = G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
again = callback (user_data);
|
again = callback (user_data);
|
||||||
|
}
|
||||||
|
|
||||||
TRACE (GLIB_IDLE_DISPATCH (source, source->context, callback, user_data, again));
|
TRACE (GLIB_IDLE_DISPATCH (source, source->context, callback, user_data, again));
|
||||||
|
|
||||||
return again;
|
return again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GSource *
|
||||||
|
idle_source_new (gboolean one_shot)
|
||||||
|
{
|
||||||
|
GSource *source;
|
||||||
|
GIdleSource *idle_source;
|
||||||
|
|
||||||
|
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. */
|
||||||
|
g_source_set_static_name (source, "GIdleSource");
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_idle_source_new:
|
* g_idle_source_new:
|
||||||
*
|
*
|
||||||
@ -6016,16 +6043,35 @@ g_idle_dispatch (GSource *source,
|
|||||||
**/
|
**/
|
||||||
GSource *
|
GSource *
|
||||||
g_idle_source_new (void)
|
g_idle_source_new (void)
|
||||||
|
{
|
||||||
|
return idle_source_new (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
idle_add_full (gint priority,
|
||||||
|
gboolean one_shot,
|
||||||
|
GSourceFunc function,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify notify)
|
||||||
{
|
{
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
guint id;
|
||||||
|
|
||||||
source = g_source_new (&g_idle_funcs, sizeof (GSource));
|
g_return_val_if_fail (function != NULL, 0);
|
||||||
g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE);
|
|
||||||
|
|
||||||
/* Set a default name on the source, just in case the caller does not. */
|
source = idle_source_new (one_shot);
|
||||||
g_source_set_static_name (source, "GIdleSource");
|
|
||||||
|
|
||||||
return source;
|
if (priority != G_PRIORITY_DEFAULT_IDLE)
|
||||||
|
g_source_set_priority (source, priority);
|
||||||
|
|
||||||
|
g_source_set_callback (source, function, data, notify);
|
||||||
|
id = g_source_attach (source, NULL);
|
||||||
|
|
||||||
|
TRACE (GLIB_IDLE_ADD (source, g_main_context_default (), id, priority, function, data));
|
||||||
|
|
||||||
|
g_source_unref (source);
|
||||||
|
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -6059,24 +6105,7 @@ g_idle_add_full (gint priority,
|
|||||||
gpointer data,
|
gpointer data,
|
||||||
GDestroyNotify notify)
|
GDestroyNotify notify)
|
||||||
{
|
{
|
||||||
GSource *source;
|
return idle_add_full (priority, FALSE, function, data, notify);
|
||||||
guint id;
|
|
||||||
|
|
||||||
g_return_val_if_fail (function != NULL, 0);
|
|
||||||
|
|
||||||
source = g_idle_source_new ();
|
|
||||||
|
|
||||||
if (priority != G_PRIORITY_DEFAULT_IDLE)
|
|
||||||
g_source_set_priority (source, priority);
|
|
||||||
|
|
||||||
g_source_set_callback (source, function, data, notify);
|
|
||||||
id = g_source_attach (source, NULL);
|
|
||||||
|
|
||||||
TRACE (GLIB_IDLE_ADD (source, g_main_context_default (), id, priority, function, data));
|
|
||||||
|
|
||||||
g_source_unref (source);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -6130,15 +6159,7 @@ guint
|
|||||||
g_idle_add_once (GSourceOnceFunc function,
|
g_idle_add_once (GSourceOnceFunc function,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
OnceData *once_data;
|
return idle_add_full (G_PRIORITY_DEFAULT_IDLE, TRUE, (GSourceFunc) function, data, NULL);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user