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