mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-04 02:06:18 +01:00
Merge branch 'ebassi/source-once' into 'main'
Add one-shot idle and timeout functions See merge request GNOME/glib!2684
This commit is contained in:
commit
93bf87528d
@ -904,6 +904,7 @@ g_main_context_pop_thread_default
|
|||||||
g_timeout_source_new
|
g_timeout_source_new
|
||||||
g_timeout_source_new_seconds
|
g_timeout_source_new_seconds
|
||||||
g_timeout_add
|
g_timeout_add
|
||||||
|
g_timeout_add_once
|
||||||
g_timeout_add_full
|
g_timeout_add_full
|
||||||
g_timeout_add_seconds
|
g_timeout_add_seconds
|
||||||
g_timeout_add_seconds_full
|
g_timeout_add_seconds_full
|
||||||
@ -911,6 +912,7 @@ g_timeout_add_seconds_full
|
|||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
g_idle_source_new
|
g_idle_source_new
|
||||||
g_idle_add
|
g_idle_add
|
||||||
|
g_idle_add_once
|
||||||
g_idle_add_full
|
g_idle_add_full
|
||||||
g_idle_remove_by_data
|
g_idle_remove_by_data
|
||||||
|
|
||||||
@ -954,6 +956,7 @@ g_source_get_context
|
|||||||
g_source_set_callback
|
g_source_set_callback
|
||||||
GSourceFunc
|
GSourceFunc
|
||||||
G_SOURCE_FUNC
|
G_SOURCE_FUNC
|
||||||
|
GSourceOnceFunc
|
||||||
g_source_set_callback_indirect
|
g_source_set_callback_indirect
|
||||||
g_source_set_ready_time
|
g_source_set_ready_time
|
||||||
g_source_get_ready_time
|
g_source_get_ready_time
|
||||||
|
93
glib/gmain.c
93
glib/gmain.c
@ -5157,6 +5157,66 @@ 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:
|
||||||
|
* @interval: the time after which the function will be called, in
|
||||||
|
* milliseconds (1/1000ths of a second)
|
||||||
|
* @function: function to call
|
||||||
|
* @data: data to pass to @function
|
||||||
|
*
|
||||||
|
* Sets a function to be called after @interval milliseconds have elapsed,
|
||||||
|
* with the default priority, %G_PRIORITY_DEFAULT.
|
||||||
|
*
|
||||||
|
* The given @function is called once and then the source will be automatically
|
||||||
|
* removed from the main context.
|
||||||
|
*
|
||||||
|
* This function otherwise behaves like g_timeout_add().
|
||||||
|
*
|
||||||
|
* Returns: the ID (greater than 0) of the event source
|
||||||
|
*
|
||||||
|
* Since: 2.74
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_timeout_add_seconds_full: (rename-to g_timeout_add_seconds)
|
* g_timeout_add_seconds_full: (rename-to g_timeout_add_seconds)
|
||||||
* @priority: the priority of the timeout source. Typically this will be in
|
* @priority: the priority of the timeout source. Typically this will be in
|
||||||
@ -6048,6 +6108,39 @@ g_idle_add (GSourceFunc function,
|
|||||||
return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
|
return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_idle_add_once:
|
||||||
|
* @function: function to call
|
||||||
|
* @data: data to pass to @function
|
||||||
|
*
|
||||||
|
* Adds a function to be called whenever there are no higher priority
|
||||||
|
* events pending to the default main loop. The function is given the
|
||||||
|
* default idle priority, %G_PRIORITY_DEFAULT_IDLE.
|
||||||
|
*
|
||||||
|
* The function will only be called once and then the source will be
|
||||||
|
* automatically removed from the main context.
|
||||||
|
*
|
||||||
|
* This function otherwise behaves like g_idle_add().
|
||||||
|
*
|
||||||
|
* Returns: the ID (greater than 0) of the event source
|
||||||
|
*
|
||||||
|
* Since: 2.74
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_idle_remove_by_data:
|
* g_idle_remove_by_data:
|
||||||
* @data: the data for the idle source's callback.
|
* @data: the data for the idle source's callback.
|
||||||
|
21
glib/gmain.h
21
glib/gmain.h
@ -194,6 +194,20 @@ typedef struct _GSourceFuncs GSourceFuncs;
|
|||||||
*/
|
*/
|
||||||
typedef gboolean (*GSourceFunc) (gpointer user_data);
|
typedef gboolean (*GSourceFunc) (gpointer user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GSourceOnceFunc:
|
||||||
|
* @user_data: data passed to the function, set when the source was
|
||||||
|
* created
|
||||||
|
*
|
||||||
|
* A source function that is only called once before being removed from the main
|
||||||
|
* context automatically.
|
||||||
|
*
|
||||||
|
* See: g_idle_add_once(), g_timeout_add_once()
|
||||||
|
*
|
||||||
|
* Since: 2.74
|
||||||
|
*/
|
||||||
|
typedef void (* GSourceOnceFunc) (gpointer user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* G_SOURCE_FUNC:
|
* G_SOURCE_FUNC:
|
||||||
* @f: a function pointer.
|
* @f: a function pointer.
|
||||||
@ -772,6 +786,10 @@ GLIB_AVAILABLE_IN_ALL
|
|||||||
guint g_timeout_add (guint interval,
|
guint g_timeout_add (guint interval,
|
||||||
GSourceFunc function,
|
GSourceFunc function,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
GLIB_AVAILABLE_IN_2_74
|
||||||
|
guint g_timeout_add_once (guint interval,
|
||||||
|
GSourceOnceFunc function,
|
||||||
|
gpointer data);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
guint g_timeout_add_seconds_full (gint priority,
|
guint g_timeout_add_seconds_full (gint priority,
|
||||||
guint interval,
|
guint interval,
|
||||||
@ -800,6 +818,9 @@ guint g_idle_add_full (gint priority,
|
|||||||
GSourceFunc function,
|
GSourceFunc function,
|
||||||
gpointer data,
|
gpointer data,
|
||||||
GDestroyNotify notify);
|
GDestroyNotify notify);
|
||||||
|
GLIB_AVAILABLE_IN_2_74
|
||||||
|
guint g_idle_add_once (GSourceOnceFunc function,
|
||||||
|
gpointer data);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
gboolean g_idle_remove_by_data (gpointer data);
|
gboolean g_idle_remove_by_data (gpointer data);
|
||||||
|
|
||||||
|
@ -2309,6 +2309,72 @@ test_maincontext_source_finalization_from_dispatch (gconstpointer user_data)
|
|||||||
g_main_context_unref (c);
|
g_main_context_unref (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
once_cb (gpointer user_data)
|
||||||
|
{
|
||||||
|
guint *counter = user_data;
|
||||||
|
|
||||||
|
*counter = *counter + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_maincontext_idle_once (void)
|
||||||
|
{
|
||||||
|
guint counter = 0;
|
||||||
|
guint source_id;
|
||||||
|
GSource *source;
|
||||||
|
|
||||||
|
g_test_summary ("Test g_idle_add_once() works");
|
||||||
|
|
||||||
|
source_id = g_idle_add_once (once_cb, &counter);
|
||||||
|
source = g_main_context_find_source_by_id (NULL, source_id);
|
||||||
|
g_assert_nonnull (source);
|
||||||
|
g_source_ref (source);
|
||||||
|
|
||||||
|
/* Iterating the main context should dispatch the source. */
|
||||||
|
g_assert_cmpuint (counter, ==, 0);
|
||||||
|
g_main_context_iteration (NULL, FALSE);
|
||||||
|
g_assert_cmpuint (counter, ==, 1);
|
||||||
|
|
||||||
|
/* Iterating it again should not dispatch the source again. */
|
||||||
|
g_main_context_iteration (NULL, FALSE);
|
||||||
|
g_assert_cmpuint (counter, ==, 1);
|
||||||
|
g_assert_true (g_source_is_destroyed (source));
|
||||||
|
|
||||||
|
g_clear_pointer (&source, g_source_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_maincontext_timeout_once (void)
|
||||||
|
{
|
||||||
|
guint counter = 0, check_counter = 0;
|
||||||
|
guint source_id;
|
||||||
|
GSource *source;
|
||||||
|
|
||||||
|
g_test_summary ("Test g_timeout_add_once() works");
|
||||||
|
|
||||||
|
source_id = g_timeout_add_once (10 /* ms */, once_cb, &counter);
|
||||||
|
source = g_main_context_find_source_by_id (NULL, source_id);
|
||||||
|
g_assert_nonnull (source);
|
||||||
|
g_source_ref (source);
|
||||||
|
|
||||||
|
/* Iterating the main context should dispatch the source, though we have to block. */
|
||||||
|
g_assert_cmpuint (counter, ==, 0);
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
g_assert_cmpuint (counter, ==, 1);
|
||||||
|
|
||||||
|
/* Iterating it again should not dispatch the source again. We add a second
|
||||||
|
* timeout and block until that is dispatched. Given the ordering guarantees,
|
||||||
|
* we should then know whether the first one would have re-dispatched by then. */
|
||||||
|
g_timeout_add_once (30 /* ms */, once_cb, &check_counter);
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
g_assert_cmpuint (check_counter, ==, 1);
|
||||||
|
g_assert_cmpuint (counter, ==, 1);
|
||||||
|
g_assert_true (g_source_is_destroyed (source));
|
||||||
|
|
||||||
|
g_clear_pointer (&source, g_source_unref);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_steal_fd (void)
|
test_steal_fd (void)
|
||||||
{
|
{
|
||||||
@ -2363,6 +2429,9 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_data_func (name, GINT_TO_POINTER (i), test_maincontext_source_finalization_from_dispatch);
|
g_test_add_data_func (name, GINT_TO_POINTER (i), test_maincontext_source_finalization_from_dispatch);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
}
|
}
|
||||||
|
g_test_add_func ("/maincontext/idle-once", test_maincontext_idle_once);
|
||||||
|
g_test_add_func ("/maincontext/timeout-once", test_maincontext_timeout_once);
|
||||||
|
|
||||||
g_test_add_func ("/mainloop/basic", test_mainloop_basic);
|
g_test_add_func ("/mainloop/basic", test_mainloop_basic);
|
||||||
g_test_add_func ("/mainloop/timeouts", test_timeouts);
|
g_test_add_func ("/mainloop/timeouts", test_timeouts);
|
||||||
g_test_add_func ("/mainloop/priorities", test_priorities);
|
g_test_add_func ("/mainloop/priorities", test_priorities);
|
||||||
|
@ -85,13 +85,12 @@ map_or_die (const gchar *filename,
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
signal_parent (gpointer data)
|
signal_parent (gpointer data)
|
||||||
{
|
{
|
||||||
#ifndef G_OS_WIN32
|
#ifndef G_OS_WIN32
|
||||||
kill (parent_pid, SIGUSR1);
|
kill (parent_pid, SIGUSR1);
|
||||||
#endif
|
#endif
|
||||||
return G_SOURCE_REMOVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -113,7 +112,7 @@ child_main (void)
|
|||||||
#endif
|
#endif
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
g_idle_add (check_stop, loop);
|
g_idle_add (check_stop, loop);
|
||||||
g_idle_add (signal_parent, NULL);
|
g_idle_add_once (signal_parent, NULL);
|
||||||
g_main_loop_run (loop);
|
g_main_loop_run (loop);
|
||||||
|
|
||||||
g_test_message ("test_child_private: received parent signal");
|
g_test_message ("test_child_private: received parent signal");
|
||||||
|
@ -5,12 +5,10 @@
|
|||||||
|
|
||||||
static GMainLoop *loop;
|
static GMainLoop *loop;
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
stop_waiting (gpointer data)
|
stop_waiting (gpointer data)
|
||||||
{
|
{
|
||||||
g_main_loop_quit (loop);
|
g_main_loop_quit (loop);
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -44,7 +42,7 @@ test_seconds (void)
|
|||||||
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=642052");
|
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=642052");
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
g_timeout_add (2100, stop_waiting, NULL);
|
g_timeout_add_once (2100, stop_waiting, NULL);
|
||||||
id = g_timeout_add_seconds (21475, unreachable_callback, NULL);
|
id = g_timeout_add_seconds (21475, unreachable_callback, NULL);
|
||||||
|
|
||||||
g_main_loop_run (loop);
|
g_main_loop_run (loop);
|
||||||
@ -81,7 +79,7 @@ test_weeks_overflow (void)
|
|||||||
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1600");
|
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1600");
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
g_timeout_add (2100, stop_waiting, NULL);
|
g_timeout_add_once (2100, stop_waiting, NULL);
|
||||||
interval_seconds = 1 + G_MAXUINT / 1000;
|
interval_seconds = 1 + G_MAXUINT / 1000;
|
||||||
id = g_timeout_add_seconds (interval_seconds, unreachable_callback, NULL);
|
id = g_timeout_add_seconds (interval_seconds, unreachable_callback, NULL);
|
||||||
|
|
||||||
|
@ -767,11 +767,10 @@ test_os_info (void)
|
|||||||
g_free (contents);
|
g_free (contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
source_test (gpointer data)
|
source_test (gpointer data)
|
||||||
{
|
{
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
return G_SOURCE_REMOVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -779,13 +778,13 @@ test_clear_source (void)
|
|||||||
{
|
{
|
||||||
guint id;
|
guint id;
|
||||||
|
|
||||||
id = g_idle_add (source_test, NULL);
|
id = g_idle_add_once (source_test, NULL);
|
||||||
g_assert_cmpuint (id, >, 0);
|
g_assert_cmpuint (id, >, 0);
|
||||||
|
|
||||||
g_clear_handle_id (&id, g_source_remove);
|
g_clear_handle_id (&id, g_source_remove);
|
||||||
g_assert_cmpuint (id, ==, 0);
|
g_assert_cmpuint (id, ==, 0);
|
||||||
|
|
||||||
id = g_timeout_add (100, source_test, NULL);
|
id = g_timeout_add_once (100, source_test, NULL);
|
||||||
g_assert_cmpuint (id, >, 0);
|
g_assert_cmpuint (id, >, 0);
|
||||||
|
|
||||||
g_clear_handle_id (&id, g_source_remove);
|
g_clear_handle_id (&id, g_source_remove);
|
||||||
|
Loading…
Reference in New Issue
Block a user