From 3abf23b2a7958bbbed44da519bee681651053f9d Mon Sep 17 00:00:00 2001 From: Peter Eisenmann Date: Sun, 16 Apr 2023 21:20:59 +0200 Subject: add g_timeout_add_seconds_once Add a new call combing behaviors of g_timeout_add_seconds and g_timeout_add_once. --- docs/reference/glib/glib-sections.txt.in | 1 + glib/gmain.c | 20 ++++++++++++++++++++ glib/gmain.h | 4 ++++ glib/tests/timeout.c | 20 ++++++++++++++++++++ 4 files changed, 45 insertions(+) diff --git a/docs/reference/glib/glib-sections.txt.in b/docs/reference/glib/glib-sections.txt.in index a674f8320..e7c3eda1b 100644 --- a/docs/reference/glib/glib-sections.txt.in +++ b/docs/reference/glib/glib-sections.txt.in @@ -586,6 +586,7 @@ g_timeout_add_once g_timeout_add_full g_timeout_add_seconds g_timeout_add_seconds_full +g_timeout_add_seconds_once g_idle_source_new diff --git a/glib/gmain.c b/glib/gmain.c index 13724c67f..9d9c123af 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -5471,6 +5471,26 @@ g_timeout_add_seconds (guint interval, return g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval, function, data, NULL); } +/** + * g_timeout_add_seconds_once: + * @interval: the time after which the function will be called, in seconds + * @function: function to call + * @data: data to pass to @function + * + * This function behaves like g_timeout_add_once() but with a range in seconds. + * + * Returns: the ID (greater than 0) of the event source + * + * Since: 2.78 + */ +guint +g_timeout_add_seconds_once (guint interval, + GSourceOnceFunc function, + gpointer data) +{ + return timeout_add_full (G_PRIORITY_DEFAULT, interval, TRUE, TRUE, (GSourceFunc) function, data, NULL); +} + /* Child watch functions */ #ifdef G_OS_WIN32 diff --git a/glib/gmain.h b/glib/gmain.h index ae3cc3ec5..7109e63dc 100644 --- a/glib/gmain.h +++ b/glib/gmain.h @@ -800,6 +800,10 @@ GLIB_AVAILABLE_IN_ALL guint g_timeout_add_seconds (guint interval, GSourceFunc function, gpointer data); +GLIB_AVAILABLE_IN_2_78 +guint g_timeout_add_seconds_once (guint interval, + GSourceOnceFunc function, + gpointer data); GLIB_AVAILABLE_IN_ALL guint g_child_watch_add_full (gint priority, GPid pid, diff --git a/glib/tests/timeout.c b/glib/tests/timeout.c index acbb8f3e1..1ae3f3a34 100644 --- a/glib/tests/timeout.c +++ b/glib/tests/timeout.c @@ -19,6 +19,12 @@ unreachable_callback (gpointer data) return G_SOURCE_REMOVE; } +static void +unreachable_void_callback (gpointer data) +{ + g_assert_not_reached (); +} + static void test_seconds (void) { @@ -51,6 +57,19 @@ test_seconds (void) g_source_remove (id); } +static void +test_seconds_once (void) +{ + /* Use the same principle as in test_seconds() */ + loop = g_main_loop_new (NULL, FALSE); + + g_timeout_add_once (2100, stop_waiting, NULL); + g_timeout_add_seconds_once (21475, unreachable_void_callback, NULL); + + g_main_loop_run (loop); + g_main_loop_unref (loop); +} + static void test_weeks_overflow (void) { @@ -192,6 +211,7 @@ main (int argc, char *argv[]) g_test_init (&argc, &argv, NULL); g_test_add_func ("/timeout/seconds", test_seconds); + g_test_add_func ("/timeout/seconds-once", test_seconds_once); g_test_add_func ("/timeout/weeks-overflow", test_weeks_overflow); g_test_add_func ("/timeout/far-future-ready-time", test_far_future_ready_time); g_test_add_func ("/timeout/rounding", test_rounding); -- cgit v1.2.1 From 467b9177197543bfef8928b7b11439e09bd3068b Mon Sep 17 00:00:00 2001 From: Peter Eisenmann Date: Sun, 16 Apr 2023 21:46:56 +0200 Subject: gtimeout: use helper for seconds_full variant Use timeout_add_full() helper to deduplicate code --- glib/gmain.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/glib/gmain.c b/glib/gmain.c index 9d9c123af..b994b59b1 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -5410,21 +5410,7 @@ g_timeout_add_seconds_full (gint priority, gpointer data, GDestroyNotify notify) { - GSource *source; - guint id; - - g_return_val_if_fail (function != NULL, 0); - - source = g_timeout_source_new_seconds (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); - g_source_unref (source); - - return id; + return timeout_add_full (priority, interval, TRUE, FALSE, function, data, notify); } /** -- cgit v1.2.1 From e25a4f995fdabd29e769ad75fe0edc8d274c01da Mon Sep 17 00:00:00 2001 From: Peter Eisenmann Date: Sun, 16 Apr 2023 21:49:10 +0200 Subject: use g_timeout_add_seconds_once() Use the newly added g_timeout_add_seconds_once() where appropriate. --- gio/gtestdbus.c | 5 ++--- gio/tests/file.c | 6 ++---- gio/tests/gapplication.c | 6 ++---- gio/tests/gdbus-connection-slow.c | 10 ++++------ gio/tests/gmenumodel.c | 6 ++---- gio/tests/gsubprocess.c | 12 ++++-------- 6 files changed, 16 insertions(+), 29 deletions(-) diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c index 8c5de3355..9ff74e653 100644 --- a/gio/gtestdbus.c +++ b/gio/gtestdbus.c @@ -62,13 +62,12 @@ typedef struct gboolean timed_out; } WeakNotifyData; -static gboolean +static void on_weak_notify_timeout (gpointer user_data) { WeakNotifyData *data = user_data; data->timed_out = TRUE; g_main_loop_quit (data->loop); - return FALSE; } static gboolean @@ -95,7 +94,7 @@ _g_object_unref_and_wait_weak_notify (gpointer object) g_idle_add (unref_on_idle, object); /* Make sure we don't block forever */ - timeout_id = g_timeout_add_seconds (30, on_weak_notify_timeout, &data); + timeout_id = g_timeout_add_seconds_once (30, on_weak_notify_timeout, &data); g_main_loop_run (data.loop); diff --git a/gio/tests/file.c b/gio/tests/file.c index ad2f945f9..754c6c326 100644 --- a/gio/tests/file.c +++ b/gio/tests/file.c @@ -452,15 +452,13 @@ created_cb (GObject *source, data); } -static gboolean +static void stop_timeout (gpointer user_data) { CreateDeleteData *data = user_data; data->timed_out = TRUE; g_main_context_wakeup (data->context); - - return G_SOURCE_REMOVE; } /* @@ -518,7 +516,7 @@ test_create_delete (gconstpointer d) /* Use the global default main context */ data->context = NULL; - data->timeout = g_timeout_add_seconds (10, stop_timeout, data); + data->timeout = g_timeout_add_seconds_once (10, stop_timeout, data); g_file_create_async (data->file, 0, 0, NULL, created_cb, data); diff --git a/gio/tests/gapplication.c b/gio/tests/gapplication.c index 1a2600099..b0584eb5f 100644 --- a/gio/tests/gapplication.c +++ b/gio/tests/gapplication.c @@ -1117,15 +1117,13 @@ activate (gpointer data) /* GApplication complains if we don't connect to ::activate */ } -static gboolean +static void quit_already (gpointer user_data) { TestReplaceData *data = user_data; g_application_quit (data->app); data->timeout_id = 0; - - return G_SOURCE_REMOVE; } static void @@ -1177,7 +1175,7 @@ test_replace (gconstpointer data) g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); if (!allow) - data.timeout_id = g_timeout_add_seconds (1, quit_already, &data); + data.timeout_id = g_timeout_add_seconds_once (1, quit_already, &data); g_application_run (app, G_N_ELEMENTS (argv) - 1, argv); diff --git a/gio/tests/gdbus-connection-slow.c b/gio/tests/gdbus-connection-slow.c index 5a3479234..06f59493c 100644 --- a/gio/tests/gdbus-connection-slow.c +++ b/gio/tests/gdbus-connection-slow.c @@ -128,14 +128,12 @@ test_connection_flush (void) /* the test will fail if the service name has not appeared after this amount of seconds */ #define LARGE_MESSAGE_TIMEOUT_SECONDS 10 -static gboolean +static void large_message_timeout_cb (gpointer data) { (void)data; g_error ("Error: timeout waiting for dbus name to appear"); - - return G_SOURCE_REMOVE; } static void @@ -200,9 +198,9 @@ test_connection_large_message (void) /* this is safe; testserver will exit once the bus goes away */ g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); - timeout_id = g_timeout_add_seconds (LARGE_MESSAGE_TIMEOUT_SECONDS, - large_message_timeout_cb, - NULL); + timeout_id = g_timeout_add_seconds_once (LARGE_MESSAGE_TIMEOUT_SECONDS, + large_message_timeout_cb, + NULL); watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION, "com.example.TestService", diff --git a/gio/tests/gmenumodel.c b/gio/tests/gmenumodel.c index fb52b4c6d..d75f36a29 100644 --- a/gio/tests/gmenumodel.c +++ b/gio/tests/gmenumodel.c @@ -7,12 +7,10 @@ #include "glib/glib-private.h" -static gboolean +static void time_out (gpointer unused G_GNUC_UNUSED) { g_error ("Timed out"); - /* not reached */ - return FALSE; } static guint @@ -22,7 +20,7 @@ add_timeout (guint seconds) /* Safety-catch against the main loop having blocked */ alarm (seconds + 5); #endif - return g_timeout_add_seconds (seconds, time_out, NULL); + return g_timeout_add_seconds_once (seconds, time_out, NULL); } static void diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c index 515a11267..30947596e 100644 --- a/gio/tests/gsubprocess.c +++ b/gio/tests/gsubprocess.c @@ -1288,14 +1288,12 @@ test_communicate_utf8_invalid (void) g_object_unref (proc); } -static gboolean +static void send_terminate (gpointer user_data) { GSubprocess *proc = user_data; g_subprocess_force_exit (proc); - - return FALSE; } static void @@ -1341,7 +1339,7 @@ test_terminate (void) g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop); - g_timeout_add_seconds (3, send_terminate, proc); + g_timeout_add_seconds_once (3, send_terminate, proc); g_main_loop_run (loop); @@ -1350,14 +1348,12 @@ test_terminate (void) } #ifdef G_OS_UNIX -static gboolean +static void send_signal (gpointer user_data) { GSubprocess *proc = user_data; g_subprocess_send_signal (proc, SIGKILL); - - return FALSE; } static void @@ -1378,7 +1374,7 @@ test_signal (void) g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop); - g_timeout_add_seconds (3, send_signal, proc); + g_timeout_add_seconds_once (3, send_signal, proc); g_main_loop_run (loop); -- cgit v1.2.1