Use G_SOURCE_CONTINUE/REMOVE internally
[platform/upstream/glib.git] / glib / tests / timeout.c
1 #include <glib.h>
2 #include <unistd.h>
3
4 static GMainLoop *loop;
5
6 static gboolean
7 stop_waiting (gpointer data)
8 {
9   g_main_loop_quit (loop);
10
11   return G_SOURCE_REMOVE;
12 }
13
14 static gboolean
15 function (gpointer data)
16 {
17   g_assert_not_reached ();
18
19   return G_SOURCE_REMOVE;
20 }
21
22 static void
23 test_seconds (void)
24 {
25   /* Bug 642052 mentions that g_timeout_add_seconds(21475) schedules a
26    * job that runs once per second.
27    *
28    * Test that that isn't true anymore by scheduling two jobs:
29    *   - one, as above
30    *   - another that runs in 2100ms
31    *
32    * If everything is working properly, the 2100ms one should run first
33    * (and exit the mainloop).  If we ever see the 21475 second job run
34    * then we have trouble (since it ran in less than 2 seconds).
35    *
36    * We need a timeout of at least 2 seconds because
37    * g_timeout_add_second can add as much as an additional second of
38    * latency.
39    */
40   loop = g_main_loop_new (NULL, FALSE);
41
42   g_timeout_add (2100, stop_waiting, NULL);
43   g_timeout_add_seconds (21475, function, NULL);
44
45   g_main_loop_run (loop);
46   g_main_loop_unref (loop);
47 }
48
49 static gint64 last_time;
50 static gint count;
51
52 static gboolean
53 test_func (gpointer data)
54 {
55   gint64 current_time;
56
57   current_time = g_get_monotonic_time ();
58
59   /* We accept 2 on the first iteration because _add_seconds() can
60    * have an initial latency of 1 second, see its documentation.
61    */
62   if (count == 0)
63     g_assert (current_time / 1000000 - last_time / 1000000 <= 2);
64   else
65     g_assert (current_time / 1000000 - last_time / 1000000 == 1);
66
67   last_time = current_time;
68   count++;
69
70   /* Make the timeout take up to 0.1 seconds.
71    * We should still get scheduled for the next second.
72    */
73   g_usleep (count * 10000);
74
75   if (count < 10)
76     return TRUE;
77
78   g_main_loop_quit (loop);
79
80   return FALSE;
81 }
82
83 static void
84 test_rounding (void)
85 {
86   loop = g_main_loop_new (NULL, FALSE);
87
88   last_time = g_get_monotonic_time ();
89   g_timeout_add_seconds (1, test_func, NULL);
90
91   g_main_loop_run (loop);
92   g_main_loop_unref (loop);
93 }
94
95 int
96 main (int argc, char *argv[])
97 {
98   g_test_init (&argc, &argv, NULL);
99
100   g_test_add_func ("/timeout/seconds", test_seconds);
101   g_test_add_func ("/timeout/rounding", test_rounding);
102
103   return g_test_run ();
104 }