#include #ifdef G_OS_UNIX #include #endif static GMainLoop *loop; static gboolean stop_waiting (gpointer data) { g_main_loop_quit (loop); return G_SOURCE_REMOVE; } static gboolean function (gpointer data) { g_assert_not_reached (); return G_SOURCE_REMOVE; } static void test_seconds (void) { guint id; /* Bug 642052 mentions that g_timeout_add_seconds(21475) schedules a * job that runs once per second. * * Test that that isn't true anymore by scheduling two jobs: * - one, as above * - another that runs in 2100ms * * If everything is working properly, the 2100ms one should run first * (and exit the mainloop). If we ever see the 21475 second job run * then we have trouble (since it ran in less than 2 seconds). * * We need a timeout of at least 2 seconds because * g_timeout_add_second can add as much as an additional second of * latency. */ loop = g_main_loop_new (NULL, FALSE); g_timeout_add (2100, stop_waiting, NULL); id = g_timeout_add_seconds (21475, function, NULL); g_main_loop_run (loop); g_main_loop_unref (loop); g_source_remove (id); } static gint64 last_time; static gint count; static gboolean test_func (gpointer data) { gint64 current_time; current_time = g_get_monotonic_time (); /* We accept 2 on the first iteration because _add_seconds() can * have an initial latency of 1 second, see its documentation. */ if (count == 0) g_assert (current_time / 1000000 - last_time / 1000000 <= 2); else g_assert (current_time / 1000000 - last_time / 1000000 == 1); last_time = current_time; count++; /* Make the timeout take up to 0.1 seconds. * We should still get scheduled for the next second. */ g_usleep (count * 10000); if (count < 10) return TRUE; g_main_loop_quit (loop); return FALSE; } static void test_rounding (void) { loop = g_main_loop_new (NULL, FALSE); last_time = g_get_monotonic_time (); g_timeout_add_seconds (1, test_func, NULL); g_main_loop_run (loop); g_main_loop_unref (loop); } int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/timeout/seconds", test_seconds); g_test_add_func ("/timeout/rounding", test_rounding); return g_test_run (); }