mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 19:36:18 +01:00
tests/mainloop: add a test for child sources
https://bugzilla.gnome.org/show_bug.cgi?id=669260
This commit is contained in:
parent
a49568cecc
commit
bdbb531340
@ -312,6 +312,103 @@ test_invoke (void)
|
||||
g_assert_cmpint (count, ==, 3);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
run_inner_loop (gpointer user_data)
|
||||
{
|
||||
GMainContext *ctx = user_data;
|
||||
GMainLoop *inner;
|
||||
GSource *timeout;
|
||||
|
||||
a++;
|
||||
|
||||
inner = g_main_loop_new (ctx, FALSE);
|
||||
timeout = g_timeout_source_new (100);
|
||||
g_source_set_callback (timeout, (GSourceFunc)g_main_loop_quit, inner, NULL);
|
||||
g_source_attach (timeout, ctx);
|
||||
|
||||
g_main_loop_run (inner);
|
||||
g_main_loop_unref (inner);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_child_sources (void)
|
||||
{
|
||||
GMainContext *ctx;
|
||||
GMainLoop *loop;
|
||||
GSource *parent, *child_b, *child_c, *end;
|
||||
|
||||
ctx = g_main_context_new ();
|
||||
loop = g_main_loop_new (ctx, FALSE);
|
||||
|
||||
a = b = c = 0;
|
||||
|
||||
parent = g_timeout_source_new (2000);
|
||||
g_source_set_callback (parent, run_inner_loop, ctx, NULL);
|
||||
g_source_set_priority (parent, G_PRIORITY_LOW);
|
||||
g_source_attach (parent, ctx);
|
||||
|
||||
child_b = g_timeout_source_new (250);
|
||||
g_source_set_callback (child_b, count_calls, &b, NULL);
|
||||
g_source_add_child_source (parent, child_b);
|
||||
|
||||
child_c = g_timeout_source_new (330);
|
||||
g_source_set_callback (child_c, count_calls, &c, NULL);
|
||||
g_source_set_priority (child_c, G_PRIORITY_HIGH);
|
||||
g_source_add_child_source (parent, child_c);
|
||||
|
||||
/* Child sources always have the priority of the parent */
|
||||
g_assert_cmpint (g_source_get_priority (parent), ==, G_PRIORITY_LOW);
|
||||
g_assert_cmpint (g_source_get_priority (child_b), ==, G_PRIORITY_LOW);
|
||||
g_assert_cmpint (g_source_get_priority (child_c), ==, G_PRIORITY_LOW);
|
||||
g_source_set_priority (parent, G_PRIORITY_DEFAULT);
|
||||
g_assert_cmpint (g_source_get_priority (parent), ==, G_PRIORITY_DEFAULT);
|
||||
g_assert_cmpint (g_source_get_priority (child_b), ==, G_PRIORITY_DEFAULT);
|
||||
g_assert_cmpint (g_source_get_priority (child_c), ==, G_PRIORITY_DEFAULT);
|
||||
|
||||
end = g_timeout_source_new (1050);
|
||||
g_source_set_callback (end, (GSourceFunc)g_main_loop_quit, loop, NULL);
|
||||
g_source_attach (end, ctx);
|
||||
g_source_unref (end);
|
||||
|
||||
g_main_loop_run (loop);
|
||||
|
||||
/* The parent source's own timeout will never trigger, so "a" will
|
||||
* only get incremented when "b" or "c" does. And when timeouts get
|
||||
* blocked, they still wait the full interval next time rather than
|
||||
* "catching up". So the timing is:
|
||||
*
|
||||
* 250 - b++ -> a++, run_inner_loop
|
||||
* 330 - (c is blocked)
|
||||
* 350 - inner_loop ends
|
||||
* 350 - c++ belatedly -> a++, run_inner_loop
|
||||
* 450 - inner loop ends
|
||||
* 500 - b++ -> a++, run_inner_loop
|
||||
* 600 - inner_loop ends
|
||||
* 680 - c++ -> a++, run_inner_loop
|
||||
* 750 - (b is blocked)
|
||||
* 780 - inner loop ends
|
||||
* 780 - b++ belatedly -> a++, run_inner_loop
|
||||
* 880 - inner loop ends
|
||||
* 1010 - c++ -> a++, run_inner_loop
|
||||
* 1030 - (b is blocked)
|
||||
* 1050 - end runs, quits outer loop, which has no effect yet
|
||||
* 1110 - inner loop ends, a returns, outer loop exits
|
||||
*/
|
||||
|
||||
g_assert_cmpint (a, ==, 6);
|
||||
g_assert_cmpint (b, ==, 3);
|
||||
g_assert_cmpint (c, ==, 3);
|
||||
|
||||
g_source_unref (parent);
|
||||
g_source_unref (child_b);
|
||||
g_source_unref (child_c);
|
||||
|
||||
g_main_loop_unref (loop);
|
||||
g_main_context_unref (ctx);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -322,6 +419,7 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/mainloop/timeouts", test_timeouts);
|
||||
g_test_add_func ("/mainloop/priorities", test_priorities);
|
||||
g_test_add_func ("/mainloop/invoke", test_invoke);
|
||||
g_test_add_func ("/mainloop/child_sources", test_child_sources);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user