Merge branch 'wip/p3732/timeout-seconds-once' into 'main'

add g_timeout_add_seconds_once

See merge request GNOME/glib!3383
This commit is contained in:
Philip Withnall 2023-05-09 12:50:39 +00:00
commit 63e1e83c33
10 changed files with 62 additions and 44 deletions

View File

@ -586,6 +586,7 @@ 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
g_timeout_add_seconds_once
<SUBSECTION> <SUBSECTION>
g_idle_source_new g_idle_source_new

View File

@ -62,13 +62,12 @@ typedef struct
gboolean timed_out; gboolean timed_out;
} WeakNotifyData; } WeakNotifyData;
static gboolean static void
on_weak_notify_timeout (gpointer user_data) on_weak_notify_timeout (gpointer user_data)
{ {
WeakNotifyData *data = user_data; WeakNotifyData *data = user_data;
data->timed_out = TRUE; data->timed_out = TRUE;
g_main_loop_quit (data->loop); g_main_loop_quit (data->loop);
return FALSE;
} }
static gboolean static gboolean
@ -95,7 +94,7 @@ _g_object_unref_and_wait_weak_notify (gpointer object)
g_idle_add (unref_on_idle, object); g_idle_add (unref_on_idle, object);
/* Make sure we don't block forever */ /* 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); g_main_loop_run (data.loop);

View File

@ -452,15 +452,13 @@ created_cb (GObject *source,
data); data);
} }
static gboolean static void
stop_timeout (gpointer user_data) stop_timeout (gpointer user_data)
{ {
CreateDeleteData *data = user_data; CreateDeleteData *data = user_data;
data->timed_out = TRUE; data->timed_out = TRUE;
g_main_context_wakeup (data->context); 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 */ /* Use the global default main context */
data->context = NULL; 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); g_file_create_async (data->file, 0, 0, NULL, created_cb, data);

View File

@ -1117,15 +1117,13 @@ activate (gpointer data)
/* GApplication complains if we don't connect to ::activate */ /* GApplication complains if we don't connect to ::activate */
} }
static gboolean static void
quit_already (gpointer user_data) quit_already (gpointer user_data)
{ {
TestReplaceData *data = user_data; TestReplaceData *data = user_data;
g_application_quit (data->app); g_application_quit (data->app);
data->timeout_id = 0; data->timeout_id = 0;
return G_SOURCE_REMOVE;
} }
static void static void
@ -1177,7 +1175,7 @@ test_replace (gconstpointer data)
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
if (!allow) 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); g_application_run (app, G_N_ELEMENTS (argv) - 1, argv);

View File

@ -128,14 +128,12 @@ test_connection_flush (void)
/* the test will fail if the service name has not appeared after this amount of seconds */ /* the test will fail if the service name has not appeared after this amount of seconds */
#define LARGE_MESSAGE_TIMEOUT_SECONDS 10 #define LARGE_MESSAGE_TIMEOUT_SECONDS 10
static gboolean static void
large_message_timeout_cb (gpointer data) large_message_timeout_cb (gpointer data)
{ {
(void)data; (void)data;
g_error ("Error: timeout waiting for dbus name to appear"); g_error ("Error: timeout waiting for dbus name to appear");
return G_SOURCE_REMOVE;
} }
static void static void
@ -200,7 +198,7 @@ test_connection_large_message (void)
/* this is safe; testserver will exit once the bus goes away */ /* 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)); 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, timeout_id = g_timeout_add_seconds_once (LARGE_MESSAGE_TIMEOUT_SECONDS,
large_message_timeout_cb, large_message_timeout_cb,
NULL); NULL);

View File

@ -7,12 +7,10 @@
#include "glib/glib-private.h" #include "glib/glib-private.h"
static gboolean static void
time_out (gpointer unused G_GNUC_UNUSED) time_out (gpointer unused G_GNUC_UNUSED)
{ {
g_error ("Timed out"); g_error ("Timed out");
/* not reached */
return FALSE;
} }
static guint static guint
@ -22,7 +20,7 @@ add_timeout (guint seconds)
/* Safety-catch against the main loop having blocked */ /* Safety-catch against the main loop having blocked */
alarm (seconds + 5); alarm (seconds + 5);
#endif #endif
return g_timeout_add_seconds (seconds, time_out, NULL); return g_timeout_add_seconds_once (seconds, time_out, NULL);
} }
static void static void

View File

@ -1288,14 +1288,12 @@ test_communicate_utf8_invalid (void)
g_object_unref (proc); g_object_unref (proc);
} }
static gboolean static void
send_terminate (gpointer user_data) send_terminate (gpointer user_data)
{ {
GSubprocess *proc = user_data; GSubprocess *proc = user_data;
g_subprocess_force_exit (proc); g_subprocess_force_exit (proc);
return FALSE;
} }
static void static void
@ -1341,7 +1339,7 @@ test_terminate (void)
g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop); 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); g_main_loop_run (loop);
@ -1350,14 +1348,12 @@ test_terminate (void)
} }
#ifdef G_OS_UNIX #ifdef G_OS_UNIX
static gboolean static void
send_signal (gpointer user_data) send_signal (gpointer user_data)
{ {
GSubprocess *proc = user_data; GSubprocess *proc = user_data;
g_subprocess_send_signal (proc, SIGKILL); g_subprocess_send_signal (proc, SIGKILL);
return FALSE;
} }
static void static void
@ -1378,7 +1374,7 @@ test_signal (void)
g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop); 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); g_main_loop_run (loop);

View File

@ -5410,21 +5410,7 @@ g_timeout_add_seconds_full (gint priority,
gpointer data, gpointer data,
GDestroyNotify notify) GDestroyNotify notify)
{ {
GSource *source; return timeout_add_full (priority, interval, TRUE, FALSE, function, data, notify);
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;
} }
/** /**
@ -5471,6 +5457,26 @@ g_timeout_add_seconds (guint interval,
return g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval, function, data, NULL); 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 */ /* Child watch functions */
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32

View File

@ -800,6 +800,10 @@ GLIB_AVAILABLE_IN_ALL
guint g_timeout_add_seconds (guint interval, guint g_timeout_add_seconds (guint interval,
GSourceFunc function, GSourceFunc function,
gpointer data); gpointer data);
GLIB_AVAILABLE_IN_2_78
guint g_timeout_add_seconds_once (guint interval,
GSourceOnceFunc function,
gpointer data);
GLIB_AVAILABLE_IN_ALL GLIB_AVAILABLE_IN_ALL
guint g_child_watch_add_full (gint priority, guint g_child_watch_add_full (gint priority,
GPid pid, GPid pid,

View File

@ -19,6 +19,12 @@ unreachable_callback (gpointer data)
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
static void
unreachable_void_callback (gpointer data)
{
g_assert_not_reached ();
}
static void static void
test_seconds (void) test_seconds (void)
{ {
@ -51,6 +57,19 @@ test_seconds (void)
g_source_remove (id); 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 static void
test_weeks_overflow (void) test_weeks_overflow (void)
{ {
@ -192,6 +211,7 @@ main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL); g_test_init (&argc, &argv, NULL);
g_test_add_func ("/timeout/seconds", test_seconds); 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/weeks-overflow", test_weeks_overflow);
g_test_add_func ("/timeout/far-future-ready-time", test_far_future_ready_time); g_test_add_func ("/timeout/far-future-ready-time", test_far_future_ready_time);
g_test_add_func ("/timeout/rounding", test_rounding); g_test_add_func ("/timeout/rounding", test_rounding);